diff --git a/projectforge-application/src/main/resources/i18nKeys.json b/projectforge-application/src/main/resources/i18nKeys.json index 526e11baad..33242af1a1 100644 --- a/projectforge-application/src/main/resources/i18nKeys.json +++ b/projectforge-application/src/main/resources/i18nKeys.json @@ -160,11 +160,11 @@ {"i18nKey":"StringValidator.maximum","bundleName":"I18nResources","translation":"The field ''${label}'' with ${length} characters is longer than the maximum of ${maximum} characters.","translationDE":"Das Feld ''${label}'' mit ${length} Zeichen darf maximal ${maximum} Zeichen lang sein.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"StringValidator.minimum","bundleName":"I18nResources","translation":"The field ''${label}'' with ${length} characters is shorter than the minimum of ${minimum} characters.","translationDE":"Das Feld ''${label}'' mit ${length} Zeichen muss mindestens ${minimum} Zeichen lang sein.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"StringValidator.range","bundleName":"I18nResources","translation":"The field ''${label}'' with ${length} characters is not between ${minimum} and ${maximum} characters long.","translationDE":"Das Feld ''${label}'' mit ${length} Zeichen muss zwischen ${minimum} und ${maximum} Zeichen lang sein.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"access","bundleName":"I18nResources","translation":"Accessright","translationDE":"Zugriffsrecht","usedInClasses":["org.projectforge.framework.persistence.DaoConst","org.projectforge.registry.Registry","org.projectforge.rest.scripting.ScriptPagesRest","org.projectforge.web.access.AccessEditPage","org.projectforge.web.access.AccessListPage"],"usedInFiles":[]}, + {"i18nKey":"access","bundleName":"I18nResources","translation":"Accessright","translationDE":"Zugriffsrecht","usedInClasses":["org.projectforge.business.poll.filter.PollAssignment","org.projectforge.framework.persistence.DaoConst","org.projectforge.registry.Registry","org.projectforge.rest.scripting.ScriptPagesRest","org.projectforge.web.access.AccessEditPage","org.projectforge.web.access.AccessListPage"],"usedInFiles":[]}, {"i18nKey":"access.accessTable","bundleName":"I18nResources","translation":"Access table","translationDE":"Zugriffstabelle","usedInClasses":["org.projectforge.web.access.AccessEditForm"],"usedInFiles":[]}, {"i18nKey":"access.exception.demoUserHasNoAccess","bundleName":"I18nResources","translation":"The demo user is blocked for this action.","translationDE":"Der oder die Demobenutzer:in ist für diese Aktion gesperrt.","usedInClasses":["org.projectforge.framework.access.AccessCheckerImpl"],"usedInFiles":[]}, {"i18nKey":"access.exception.employeeHasNoVacationDays","bundleName":"I18nResources","translation":"The employee has no vacation days assigned","translationDE":"Dem oder der Mitarbeiter:in sind keine Urlaubstage zugewiesen","usedInClasses":["org.projectforge.business.vacation.service.VacationService"],"usedInFiles":[]}, - {"i18nKey":"access.exception.noAccess","bundleName":"I18nResources","translation":"No access.","translationDE":"Kein Zugriff.","usedInClasses":["org.projectforge.framework.persistence.api.BaseDaoSupport"],"usedInFiles":[]}, + {"i18nKey":"access.exception.noAccess","bundleName":"I18nResources","translation":"No access.","translationDE":"Kein Zugriff.","usedInClasses":["org.projectforge.framework.persistence.api.BaseDaoSupport","org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, {"i18nKey":"access.exception.noEmployeeToUser","bundleName":"I18nResources","translation":"The user has no employee assigned","translationDE":"Angemeldete:r Benutzer:in hat keinen zugehörige:n Mitarbeiter:in","usedInClasses":["org.projectforge.business.vacation.service.VacationService"],"usedInFiles":[]}, {"i18nKey":"access.exception.noReadAccess","bundleName":"I18nResources","translation":"No read-access.","translationDE":"Kein lesender Zugriff.","usedInClasses":["org.projectforge.business.common.BaseUserGroupRightUtils"],"usedInFiles":[]}, {"i18nKey":"access.exception.noUserGiven","bundleName":"I18nResources","translation":"No logged-in user given.","translationDE":"Keine:n angemeldete:n Benutzer:in gefunden.","usedInClasses":["org.projectforge.framework.access.AccessCheckerImpl"],"usedInFiles":[]}, @@ -491,11 +491,11 @@ {"i18nKey":"attachment.zip.standard","bundleName":"I18nResources","translation":"No encryption","translationDE":"ohne Verschlüsselung","usedInClasses":["org.projectforge.jcr.ZipMode"],"usedInFiles":[]}, {"i18nKey":"attachments","bundleName":"I18nResources","translation":"Attachments","translationDE":"Anhänge","usedInClasses":["org.projectforge.framework.jcr.AttachmentsService","org.projectforge.plugins.datatransfer.DataTransferNotificationMailService","org.projectforge.plugins.merlin.rest.MerlinAttachmentsActionListener","org.projectforge.ui.UIAgGridColumnDef","org.projectforge.ui.UIAttachmentList","org.projectforge.web.fibu.AuftragEditForm"],"usedInFiles":[]}, {"i18nKey":"attachments.short","bundleName":"I18nResources","translation":"Att.","translationDE":"Anh.","usedInClasses":["org.projectforge.web.fibu.AuftragListPage"],"usedInFiles":[]}, - {"i18nKey":"attr.deletemodal.heading","bundleName":"I18nResources","translation":"Would you like to delete this entry?","translationDE":"Soll dieser Eintrag wirklich gelöscht werden?","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, - {"i18nKey":"attr.deletemodal.question","bundleName":"I18nResources","translation":"Yes: This entry will be deleted and all changes on this page will be saved.
Cancel: This entry will not be deleted and you stay on this page.","translationDE":"Ja: Der Eintrag wird gelöscht und alle Änderungen auf dieser Seite werden gespeichert.
Abbrechen: Der Eintrag wird nicht gelöscht und Sie bleiben auf dieser Seite.","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, + {"i18nKey":"attr.deletemodal.heading","bundleName":"I18nResources","translation":"Would you like to delete this entry?","translationDE":"Soll dieser Eintrag wirklich gelöscht werden?","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, + {"i18nKey":"attr.deletemodal.question","bundleName":"I18nResources","translation":"Yes: This entry will be deleted and all changes on this page will be saved.
Cancel: This entry will not be deleted and you stay on this page.","translationDE":"Ja: Der Eintrag wird gelöscht und alle Änderungen auf dieser Seite werden gespeichert.
Abbrechen: Der Eintrag wird nicht gelöscht und Sie bleiben auf dieser Seite.","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, {"i18nKey":"attr.instantOfTime","bundleName":"I18nResources","translation":"Instant of time","translationDE":"Zeitpunkt","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"attr.savemodal.heading","bundleName":"I18nResources","translation":"Would you like to save the changes?","translationDE":"Soll die Änderungen gespeichert werden?","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, - {"i18nKey":"attr.savemodal.question","bundleName":"I18nResources","translation":"Yes: All changes on this page will be saved.
Cancel: The changes will not be saved but not discarded and you stay on this page.","translationDE":"Ja: Alle Änderungen auf dieser Seite werden gespeichert.
Abbrechen: Die Änderungen werden nicht gespeichert aber auch nicht verworfen und Sie bleiben auf dieser Seite.","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, + {"i18nKey":"attr.savemodal.heading","bundleName":"I18nResources","translation":"Would you like to save the changes?","translationDE":"Soll die Änderungen gespeichert werden?","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, + {"i18nKey":"attr.savemodal.question","bundleName":"I18nResources","translation":"Yes: All changes on this page will be saved.
Cancel: The changes will not be saved but not discarded and you stay on this page.","translationDE":"Ja: Alle Änderungen auf dieser Seite werden gespeichert.
Abbrechen: Die Änderungen werden nicht gespeichert aber auch nicht verworfen und Sie bleiben auf dieser Seite.","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, {"i18nKey":"attr.starttime.alreadyexists.day","bundleName":"I18nResources","translation":"There is already an entry with the same date (Day).","translationDE":"Es existiert bereits ein Eintrag mit gleichem Datum (Tag).","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, {"i18nKey":"attr.starttime.alreadyexists.month","bundleName":"I18nResources","translation":"There is already an entry with the same date (Month).","translationDE":"Es existiert bereits ein Eintrag mit gleichem Datum (Monat).","usedInClasses":["org.projectforge.web.common.timeattr.TimedAttributePanel"],"usedInFiles":[]}, {"i18nKey":"attr.validFrom","bundleName":"I18nResources","translation":"Valid from","translationDE":"Gültig ab","usedInClasses":[],"usedInFiles":[]}, @@ -754,13 +754,13 @@ {"i18nKey":"contextMenu.cancel","bundleName":"I18nResources","translation":"Cancel","translationDE":"Abbrechen","usedInClasses":["org.projectforge.web.wicket.AbstractUnsecureBasePage"],"usedInFiles":[]}, {"i18nKey":"contextMenu.newTab","bundleName":"I18nResources","translation":"Open in new tab","translationDE":"Link in neuem Tab öffnen","usedInClasses":["org.projectforge.web.wicket.AbstractUnsecureBasePage"],"usedInFiles":[]}, {"i18nKey":"copy","bundleName":"I18nResources","translation":"Copy","translationDE":"Kopieren","usedInClasses":["org.projectforge.web.teamcal.integration.TeamCalCalendarPanel"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/gantt/GanttChartEditTreeTablePanel.html"]}, - {"i18nKey":"create","bundleName":"I18nResources","translation":"Create","translationDE":"Anlegen","usedInClasses":["org.projectforge.framework.persistence.database.SchemaExport","org.projectforge.rest.GroupPagesRest","org.projectforge.rest.TimesheetFavoritesRest","org.projectforge.rest.UserPagesRest","org.projectforge.rest.calendar.CalendarServicesRest","org.projectforge.rest.task.TaskFavoritesRest","org.projectforge.ui.LayoutUtils","org.projectforge.ui.UIButton","org.projectforge.web.fibu.AbstractRechnungEditForm","org.projectforge.web.user.GroupEditForm","org.projectforge.web.user.UserEditForm","org.projectforge.web.wicket.AbstractEditForm"],"usedInFiles":[]}, + {"i18nKey":"create","bundleName":"I18nResources","translation":"Create","translationDE":"Anlegen","usedInClasses":["org.projectforge.framework.persistence.database.SchemaExport","org.projectforge.rest.GroupPagesRest","org.projectforge.rest.TimesheetFavoritesRest","org.projectforge.rest.UserPagesRest","org.projectforge.rest.calendar.CalendarServicesRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.rest.task.TaskFavoritesRest","org.projectforge.ui.LayoutUtils","org.projectforge.ui.UIButton","org.projectforge.web.fibu.AbstractRechnungEditForm","org.projectforge.web.user.GroupEditForm","org.projectforge.web.user.UserEditForm","org.projectforge.web.wicket.AbstractEditForm"],"usedInFiles":[]}, {"i18nKey":"created","bundleName":"I18nResources","translation":"created","translationDE":"angelegt","usedInClasses":["org.projectforge.business.address.AddressDao","org.projectforge.business.fibu.AuftragDO","org.projectforge.business.fibu.EingangsrechnungDO","org.projectforge.business.fibu.RechnungDO","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.humanresources.HRPlanningDO","org.projectforge.business.teamcal.event.model.CalEventDO","org.projectforge.business.teamcal.event.model.TeamEventDO","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.flyway.dbmigration.V7_0_0_6__MigrateEmployeeAndCarryVacationDays","org.projectforge.flyway.dbmigration.V7_4_1_3__ReleaseUserPassword","org.projectforge.framework.persistence.entities.AbstractBaseDO","org.projectforge.framework.persistence.entities.AbstractHistorizableBaseDO","org.projectforge.framework.renderer.PdfRenderer","org.projectforge.jcr.RepoService","org.projectforge.mail.SendMail","org.projectforge.plugins.datatransfer.rest.DataTransferAreaPagesRest","org.projectforge.plugins.licensemanagement.LicenseListPage","org.projectforge.plugins.marketing.AddressCampaignListPage","org.projectforge.plugins.marketing.AddressCampaignValueListPage","org.projectforge.plugins.marketing.rest.AddressCampaignPagesRest","org.projectforge.plugins.memo.MemoListPage","org.projectforge.plugins.memo.rest.MemoPagesRest","org.projectforge.plugins.merlin.rest.MerlinPagesRest","org.projectforge.plugins.todo.ToDoDao","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.plugins.todo.rest.ToDoPagesRest","org.projectforge.rest.AttachmentPageRest","org.projectforge.rest.BookPagesRest","org.projectforge.rest.hr.LeaveAccountEntryPagesRest","org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.rest.my2fa.My2FASetupPageRest","org.projectforge.security.webauthn.WebAuthnEntryDO","org.projectforge.ui.UIAgGridColumnDef","org.projectforge.ui.UIAttachmentList","org.projectforge.web.gantt.GanttChartListPage"],"usedInFiles":[]}, {"i18nKey":"createdBy","bundleName":"I18nResources","translation":"created by","translationDE":"angelegt von","usedInClasses":["org.projectforge.framework.persistence.jpa.impl.BaseDaoJpaAdapter","org.projectforge.rest.AttachmentPageRest","org.projectforge.ui.UIAttachmentList"],"usedInFiles":[]}, {"i18nKey":"currencyConverter.percentage.help","bundleName":"I18nResources","translation":"You can enter amounts as well as percent values (e. g. 10%).","translationDE":"Es können sowohl Beträge als auch Prozentzahlen (z. B. 10%) eingegeben werden.","usedInClasses":["org.projectforge.web.fibu.RechnungCostEditTablePanel"],"usedInFiles":[]}, {"i18nKey":"currencyFormat","bundleName":"I18nResources","translation":"{0,number,,##0.00}","translationDE":"{0,number,,##0.00}","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"datatable.no-records-found","bundleName":"I18nResources","translation":"No records found.","translationDE":"Keine Einträge gefunden.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"date","bundleName":"I18nResources","translation":"date","translationDE":"Datum","usedInClasses":["org.projectforge.business.book.BookDO","org.projectforge.business.fibu.OrderExport","org.projectforge.business.fibu.datev.EmployeeSalaryExportDao","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.orga.ContractDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.orga.PostausgangDO","org.projectforge.business.orga.PosteingangDO","org.projectforge.business.scripting.ScriptParameterType","org.projectforge.business.vacation.model.LeaveAccountEntryDO","org.projectforge.business.vacation.repository.LeaveAccountEntryDao","org.projectforge.framework.persistence.database.json.DatabaseWriter","org.projectforge.plugins.banking.BankAccountRecordPagesRest","org.projectforge.plugins.liquidityplanning.LiquidityForecastCashFlow","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.hr.LeaveAccountEntryPagesRest","org.projectforge.rest.orga.ContractPagesRest","org.projectforge.web.fibu.AccountingRecordEditForm","org.projectforge.web.fibu.DatevImportStoragePanel","org.projectforge.web.wicket.I18nParamMap","org.projectforge.web.wicket.WebConstants","org.projectforge.web.wicket.components.DateTimePanel"],"usedInFiles":["./plugins/org.projectforge.plugins.datatransfer/src/main/resources/mail/dataTransferMail.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/DateTimePanel.html"]}, + {"i18nKey":"date","bundleName":"I18nResources","translation":"date","translationDE":"Datum","usedInClasses":["org.projectforge.business.book.BookDO","org.projectforge.business.fibu.OrderExport","org.projectforge.business.fibu.datev.EmployeeSalaryExportDao","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.orga.ContractDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.orga.PostausgangDO","org.projectforge.business.orga.PosteingangDO","org.projectforge.business.poll.PollDO","org.projectforge.business.scripting.ScriptParameterType","org.projectforge.business.vacation.model.LeaveAccountEntryDO","org.projectforge.business.vacation.repository.LeaveAccountEntryDao","org.projectforge.framework.persistence.database.json.DatabaseWriter","org.projectforge.plugins.banking.BankAccountRecordPagesRest","org.projectforge.plugins.liquidityplanning.LiquidityForecastCashFlow","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.hr.LeaveAccountEntryPagesRest","org.projectforge.rest.orga.ContractPagesRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.web.fibu.AccountingRecordEditForm","org.projectforge.web.fibu.DatevImportStoragePanel","org.projectforge.web.wicket.I18nParamMap","org.projectforge.web.wicket.WebConstants","org.projectforge.web.wicket.components.DateTimePanel"],"usedInFiles":["./plugins/org.projectforge.plugins.datatransfer/src/main/resources/mail/dataTransferMail.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/DateTimePanel.html"]}, {"i18nKey":"date.begin","bundleName":"I18nResources","translation":"Start date","translationDE":"Beginndatum","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest","org.projectforge.rest.scripting.AbstractScriptExecutePageRest"],"usedInFiles":[]}, {"i18nKey":"date.end","bundleName":"I18nResources","translation":"End date","translationDE":"Endedatum","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest","org.projectforge.rest.scripting.AbstractScriptExecutePageRest"],"usedInFiles":[]}, {"i18nKey":"date.from","bundleName":"I18nResources","translation":"from","translationDE":"von","usedInClasses":[],"usedInFiles":[]}, @@ -769,11 +769,11 @@ {"i18nKey":"dateFormat.xls","bundleName":"I18nResources","translation":"Excel date format","translationDE":"Exceldatumsformat","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"day","bundleName":"I18nResources","translation":"day(s)","translationDE":"Tag(e)","usedInClasses":["org.projectforge.birthdaybutler.BirthdayButlerService","org.projectforge.business.fibu.MonthlyEmployeeReport","org.projectforge.business.gantt.GanttXUnit","org.projectforge.business.teamcal.event.RecurrenceFrequencyModeTwo","org.projectforge.framework.calendar.DayMonthYearHolder"],"usedInFiles":[]}, {"i18nKey":"days","bundleName":"I18nResources","translation":"days","translationDE":"Tage","usedInClasses":["org.projectforge.framework.calendar.WeekHolder","org.projectforge.framework.i18n.Duration","org.projectforge.framework.i18n.TimeAgo","org.projectforge.plugins.liquidityplanning.LiquidityForecastForm","org.projectforge.rest.calendar.FullCalendarEvent","org.projectforge.statistics.TimesheetDisciplineChartBuilder","org.projectforge.web.fibu.AbstractRechnungEditForm","org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, - {"i18nKey":"deadline","bundleName":"I18nResources","translation":"Deadline","translationDE":"Frist","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"deadline","bundleName":"I18nResources","translation":"Deadline","translationDE":"Frist","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.rest.poll.PollInfoPageRest","org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, {"i18nKey":"default","bundleName":"I18nResources","translation":"Default","translationDE":"Standard","usedInClasses":["org.apache.batik.util.XMLConstants","org.projectforge.business.teamcal.filter.TeamCalCalendarFilter","org.projectforge.caldav.model.AddressBook","org.projectforge.rest.calendar.CalendarSettingsPageRest","org.projectforge.web.fibu.RechnungEditPage"],"usedInFiles":[]}, {"i18nKey":"delete","bundleName":"I18nResources","translation":"Delete","translationDE":"Löschen","usedInClasses":["org.projectforge.favorites.Favorites","org.projectforge.framework.access.AccessEntryDO","org.projectforge.framework.access.OperationType","org.projectforge.framework.jcr.AttachmentsEventType","org.projectforge.model.rest.RestPaths","org.projectforge.plugins.datatransfer.restPublic.DataTransferPublicServicesRest","org.projectforge.plugins.merlin.rest.MerlinVariablePageRest","org.projectforge.rest.AddressPagesRest","org.projectforge.rest.AttachmentPageRest","org.projectforge.rest.AttachmentsServicesRest","org.projectforge.rest.TimesheetFavoritesRest","org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.rest.task.TaskFavoritesRest","org.projectforge.ui.LayoutUtils","org.projectforge.ui.UIAttachmentList","org.projectforge.web.fibu.AbstractRechnungEditForm","org.projectforge.web.fibu.AuftragEditForm","org.projectforge.web.fibu.PaymentSchedulePanel","org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.teamcal.dialog.TeamCalFilterDialog","org.projectforge.web.wicket.AbstractEditForm","org.projectforge.web.wicket.autocompletion.PFAutoCompleteTextField","org.projectforge.web.wicket.flowlayout.FileUploadPanel","org.projectforge.web.wicket.flowlayout.ImageUploadPanel"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/fibu/PaymentSchedulePanel.html"]}, {"i18nKey":"deleted","bundleName":"I18nResources","translation":"deleted","translationDE":"gelöscht","usedInClasses":["org.projectforge.business.address.AddressDao","org.projectforge.business.fibu.EmployeeDao","org.projectforge.business.fibu.ProjektFilter","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.humanresources.HRPlanningEntryDao","org.projectforge.business.teamcal.event.CalEventDao","org.projectforge.business.teamcal.event.TeamEventDao","org.projectforge.business.teamcal.event.TeamEventServiceImpl","org.projectforge.business.timesheet.TimesheetDao","org.projectforge.business.user.UserDao","org.projectforge.business.vacation.repository.VacationDao","org.projectforge.export.DOListExcelExporter","org.projectforge.flyway.dbmigration.V7_0_0_15__AuthenticationToken","org.projectforge.flyway.dbmigration.V7_0_0_6__MigrateEmployeeAndCarryVacationDays","org.projectforge.flyway.dbmigration.V7_4_1_3__ReleaseUserPassword","org.projectforge.framework.access.AccessDao","org.projectforge.framework.persistence.api.BaseDao","org.projectforge.framework.persistence.api.MagicFilterProcessor","org.projectforge.framework.persistence.api.QueryFilter","org.projectforge.framework.persistence.entities.AbstractBaseDO","org.projectforge.plugins.todo.ToDoDao","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.core.AbstractPagesRest","org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.ui.filter.LayoutListFilterUtils","org.projectforge.web.rest.TaskDaoRest","org.projectforge.web.rest.TimesheetDaoRest","org.projectforge.web.task.TaskTreeForm","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, - {"i18nKey":"description","bundleName":"I18nResources","translation":"Description","translationDE":"Beschreibung","usedInClasses":["org.projectforge.business.fibu.EmployeeDO","org.projectforge.business.fibu.KontoDO","org.projectforge.business.fibu.KundeDO","org.projectforge.business.fibu.ProjektDO","org.projectforge.business.fibu.datev.EmployeeSalaryExportDao","org.projectforge.business.fibu.kost.Kost1DO","org.projectforge.business.fibu.kost.Kost2ArtDO","org.projectforge.business.fibu.kost.Kost2DO","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.gantt.GanttChartDao","org.projectforge.business.ldap.GroupDOConverter","org.projectforge.business.ldap.LdapGroupDao","org.projectforge.business.ldap.LdapOrganizationalUnitDao","org.projectforge.business.ldap.LdapPersonDao","org.projectforge.business.ldap.PFUserDOConverter","org.projectforge.business.scripting.ScriptDO","org.projectforge.business.task.TaskDO","org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.vacation.model.LeaveAccountEntryDO","org.projectforge.framework.access.GroupTaskAccessDO","org.projectforge.framework.jcr.Attachment","org.projectforge.framework.jobs.JobHandler","org.projectforge.framework.persistence.user.entities.GroupDO","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.plugins.banking.BankAccountDO","org.projectforge.plugins.banking.BankAccountPagesRest","org.projectforge.plugins.datatransfer.rest.DataTransferAreaPagesRest","org.projectforge.plugins.datatransfer.rest.DataTransferAuditPageRest","org.projectforge.plugins.datatransfer.rest.DataTransferPageRest","org.projectforge.plugins.ihk.IHKExporter","org.projectforge.plugins.merlin.MerlinTemplateDO","org.projectforge.plugins.merlin.MerlinVariableBase","org.projectforge.plugins.merlin.rest.MerlinPagesRest","org.projectforge.plugins.todo.ToDoDO","org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.plugins.todo.rest.ToDoPagesRest","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.AddressBookPagesRest","org.projectforge.rest.GroupAccessPagesRest","org.projectforge.rest.GroupPagesRest","org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.TimesheetMultiSelectedPageRest","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.UserPagesRest","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.calendar.TimesheetEventsProvider","org.projectforge.rest.fibu.CustomerPagesRest","org.projectforge.rest.fibu.KontoPagesRest","org.projectforge.rest.fibu.ProjectMultiSelectedPageRest","org.projectforge.rest.fibu.ProjectPagesRest","org.projectforge.rest.fibu.kost.Kost1PagesRest","org.projectforge.rest.fibu.kost.Kost2ArtPagesRest","org.projectforge.rest.fibu.kost.Kost2PagesRest","org.projectforge.rest.hr.HRPlanningListPagesRest","org.projectforge.rest.hr.LeaveAccountEntryPagesRest","org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.MyScriptPagesRest","org.projectforge.rest.scripting.ScriptPagesRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.ui.UIAttachmentList","org.projectforge.web.access.AccessEditForm","org.projectforge.web.access.AccessListPage","org.projectforge.web.admin.ConfigurationEditForm","org.projectforge.web.admin.ConfigurationListPage","org.projectforge.web.calendar.TimesheetEventsProvider","org.projectforge.web.fibu.CustomerEditForm","org.projectforge.web.fibu.CustomerListPage","org.projectforge.web.fibu.KontoEditForm","org.projectforge.web.fibu.KontoListPage","org.projectforge.web.fibu.KontoSelectPanel","org.projectforge.web.fibu.Kost1EditForm","org.projectforge.web.fibu.Kost1ListPage","org.projectforge.web.fibu.Kost2ArtEditForm","org.projectforge.web.fibu.Kost2ArtListPage","org.projectforge.web.fibu.Kost2EditForm","org.projectforge.web.fibu.Kost2ListPage","org.projectforge.web.fibu.ProjektEditForm","org.projectforge.web.fibu.ProjektListPage","org.projectforge.web.fibu.ReportObjectivesPanel","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.humanresources.HRPlanningListPage","org.projectforge.web.task.TaskEditForm","org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetEditPage","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.user.GroupEditForm","org.projectforge.web.user.GroupListPage","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListPage","org.projectforge.web.wicket.ErrorForm","org.projectforge.web.wicket.FeedbackForm"],"usedInFiles":["./plugins/org.projectforge.plugins.datatransfer/src/main/resources/mail/dataTransferMail.html","./projectforge-business/src/main/resources/htmlTemplates/teamEventResponse.html","./projectforge-business/src/main/resources/mail/teamEventEmail.html","./projectforge-business/src/main/resources/mail/todoChangeNotification.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/ReportObjectivesPanel.html"]}, + {"i18nKey":"description","bundleName":"I18nResources","translation":"Description","translationDE":"Beschreibung","usedInClasses":["org.projectforge.business.fibu.EmployeeDO","org.projectforge.business.fibu.KontoDO","org.projectforge.business.fibu.KundeDO","org.projectforge.business.fibu.ProjektDO","org.projectforge.business.fibu.datev.EmployeeSalaryExportDao","org.projectforge.business.fibu.kost.Kost1DO","org.projectforge.business.fibu.kost.Kost2ArtDO","org.projectforge.business.fibu.kost.Kost2DO","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.gantt.GanttChartDao","org.projectforge.business.ldap.GroupDOConverter","org.projectforge.business.ldap.LdapGroupDao","org.projectforge.business.ldap.LdapOrganizationalUnitDao","org.projectforge.business.ldap.LdapPersonDao","org.projectforge.business.ldap.PFUserDOConverter","org.projectforge.business.poll.PollDO","org.projectforge.business.scripting.ScriptDO","org.projectforge.business.task.TaskDO","org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.vacation.model.LeaveAccountEntryDO","org.projectforge.framework.access.GroupTaskAccessDO","org.projectforge.framework.jcr.Attachment","org.projectforge.framework.jobs.JobHandler","org.projectforge.framework.persistence.user.entities.GroupDO","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.plugins.banking.BankAccountDO","org.projectforge.plugins.banking.BankAccountPagesRest","org.projectforge.plugins.datatransfer.rest.DataTransferAreaPagesRest","org.projectforge.plugins.datatransfer.rest.DataTransferAuditPageRest","org.projectforge.plugins.datatransfer.rest.DataTransferPageRest","org.projectforge.plugins.ihk.IHKExporter","org.projectforge.plugins.merlin.MerlinTemplateDO","org.projectforge.plugins.merlin.MerlinVariableBase","org.projectforge.plugins.merlin.rest.MerlinPagesRest","org.projectforge.plugins.todo.ToDoDO","org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.plugins.todo.rest.ToDoPagesRest","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.AddressBookPagesRest","org.projectforge.rest.GroupAccessPagesRest","org.projectforge.rest.GroupPagesRest","org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.TimesheetMultiSelectedPageRest","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.UserPagesRest","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.calendar.TimesheetEventsProvider","org.projectforge.rest.fibu.CustomerPagesRest","org.projectforge.rest.fibu.KontoPagesRest","org.projectforge.rest.fibu.ProjectMultiSelectedPageRest","org.projectforge.rest.fibu.ProjectPagesRest","org.projectforge.rest.fibu.kost.Kost1PagesRest","org.projectforge.rest.fibu.kost.Kost2ArtPagesRest","org.projectforge.rest.fibu.kost.Kost2PagesRest","org.projectforge.rest.hr.HRPlanningListPagesRest","org.projectforge.rest.hr.LeaveAccountEntryPagesRest","org.projectforge.rest.poll.PollInfoPageRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.MyScriptPagesRest","org.projectforge.rest.scripting.ScriptPagesRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.ui.UIAttachmentList","org.projectforge.web.access.AccessEditForm","org.projectforge.web.access.AccessListPage","org.projectforge.web.admin.ConfigurationEditForm","org.projectforge.web.admin.ConfigurationListPage","org.projectforge.web.calendar.TimesheetEventsProvider","org.projectforge.web.fibu.CustomerEditForm","org.projectforge.web.fibu.CustomerListPage","org.projectforge.web.fibu.KontoEditForm","org.projectforge.web.fibu.KontoListPage","org.projectforge.web.fibu.KontoSelectPanel","org.projectforge.web.fibu.Kost1EditForm","org.projectforge.web.fibu.Kost1ListPage","org.projectforge.web.fibu.Kost2ArtEditForm","org.projectforge.web.fibu.Kost2ArtListPage","org.projectforge.web.fibu.Kost2EditForm","org.projectforge.web.fibu.Kost2ListPage","org.projectforge.web.fibu.ProjektEditForm","org.projectforge.web.fibu.ProjektListPage","org.projectforge.web.fibu.ReportObjectivesPanel","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.humanresources.HRPlanningListPage","org.projectforge.web.task.TaskEditForm","org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetEditPage","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.user.GroupEditForm","org.projectforge.web.user.GroupListPage","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListPage","org.projectforge.web.wicket.ErrorForm","org.projectforge.web.wicket.FeedbackForm"],"usedInFiles":["./plugins/org.projectforge.plugins.datatransfer/src/main/resources/mail/dataTransferMail.html","./projectforge-business/src/main/resources/htmlTemplates/teamEventResponse.html","./projectforge-business/src/main/resources/mail/teamEventEmail.html","./projectforge-business/src/main/resources/mail/todoChangeNotification.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/ReportObjectivesPanel.html"]}, {"i18nKey":"deselectAll","bundleName":"I18nResources","translation":"Deselect all","translationDE":"Alle abwählen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"dialog.title.error","bundleName":"I18nResources","translation":"An error occured!","translationDE":"Es ist ein Fehler aufgetreten!","usedInClasses":["org.projectforge.web.dialog.ModalMessageDialog"],"usedInFiles":[]}, {"i18nKey":"dialog.title.information","bundleName":"I18nResources","translation":"Information","translationDE":"Information","usedInClasses":["org.projectforge.web.dialog.ModalMessageDialog"],"usedInFiles":[]}, @@ -820,7 +820,7 @@ {"i18nKey":"exception.pleaseContactDeveloperTeam","bundleName":"I18nResources","translation":"Internal error, please contact the developer team (the message id in error log: #{0}).","translationDE":"Interner Fehler, bitte die Entwickler:innen informieren. Die Fehlerkennung in den Fehlerprotokollen lautet #{0}.","usedInClasses":["org.projectforge.common.i18n.UserException"],"usedInFiles":[]}, {"i18nKey":"exception.scriptError","bundleName":"I18nResources","translation":"Exception while script execution thrown: {0}","translationDE":"Fehler bei der Script-Ausführung: {0}","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"execute","bundleName":"I18nResources","translation":"Execute","translationDE":"Ausführen","usedInClasses":["org.projectforge.plugins.liquidityplanning.LiquidityForecastForm","org.projectforge.plugins.merlin.rest.MerlinExecutionPageRest","org.projectforge.rest.multiselect.AbstractMultiSelectedPage","org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest","org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.GroovyConsoleForm","org.projectforge.web.admin.SqlConsoleForm"],"usedInFiles":[]}, - {"i18nKey":"export","bundleName":"I18nResources","translation":"Export","translationDE":"Export","usedInClasses":["org.projectforge.export.DOListExcelExporter","org.projectforge.plugins.eed.wicket.ExportDataForm","org.projectforge.rest.AddressPagesRest","org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationExportPageRest","org.projectforge.rest.VacationPagesRest","org.projectforge.web.address.AddressListPage","org.projectforge.web.fibu.EingangsrechnungListForm","org.projectforge.web.gantt.GanttChartEditForm","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, + {"i18nKey":"export","bundleName":"I18nResources","translation":"Export","translationDE":"Export","usedInClasses":["org.projectforge.export.DOListExcelExporter","org.projectforge.plugins.eed.wicket.ExportDataForm","org.projectforge.rest.AddressPagesRest","org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationExportPageRest","org.projectforge.rest.VacationPagesRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.web.address.AddressListPage","org.projectforge.web.fibu.EingangsrechnungListForm","org.projectforge.web.gantt.GanttChartEditForm","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"exportAsPdf","bundleName":"I18nResources","translation":"Pdf export","translationDE":"Pdf-Export","usedInClasses":["org.projectforge.web.fibu.MonthlyEmployeeReportPage","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"exportAsXls","bundleName":"I18nResources","translation":"Excel export","translationDE":"Excel-Export","usedInClasses":["org.projectforge.plugins.skillmatrix.SkillEntryPagesRest","org.projectforge.rest.VacationExportPageRest","org.projectforge.rest.core.AbstractPagesRest","org.projectforge.web.fibu.AuftragListPage","org.projectforge.web.fibu.Kost1ListPage","org.projectforge.web.fibu.Kost2ListPage","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.wicket.AbstractListPage"],"usedInFiles":[]}, {"i18nKey":"favorite","bundleName":"I18nResources","translation":"Favorite","translationDE":"Favorit","usedInClasses":["org.projectforge.rest.AddressPagesRest","org.projectforge.rest.AddressViewPageRest"],"usedInFiles":[]}, @@ -1424,7 +1424,7 @@ {"i18nKey":"hr.planning.weekend","bundleName":"I18nResources","translation":"Week-end","translationDE":"Wochenende","usedInClasses":["org.projectforge.business.humanresources.HRPlanningEntryDO","org.projectforge.web.humanresources.HRPlanningListPage"],"usedInFiles":[]}, {"i18nKey":"hr.planning.workdays","bundleName":"I18nResources","translation":"Workdays","translationDE":"Arbeitstage","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"ibanvalidator.wronglength.de","bundleName":"I18nResources","translation":"The field ''${label}'' starts with ''DE'', but a german IBAN must have 22 characters.","translationDE":"Das Feld ''${label}'' beginnt mit ''DE''. Eine deutsche IBAN muss jedoch aus 22 Zeichen bestehen.","usedInClasses":["org.projectforge.web.common.IbanValidator"],"usedInFiles":[]}, - {"i18nKey":"id","bundleName":"I18nResources","translation":"Id","translationDE":"Id","usedInClasses":["org.apache.batik.util.XMLConstants","org.projectforge.business.address.AddressExport","org.projectforge.business.address.PersonalAddressDao","org.projectforge.business.book.BookDao","org.projectforge.business.fibu.AuftragDao","org.projectforge.business.fibu.EingangsrechnungDO","org.projectforge.business.fibu.EingangsrechnungsPositionDO","org.projectforge.business.fibu.EmployeeDO","org.projectforge.business.fibu.EmployeeSalaryDao","org.projectforge.business.fibu.InvoiceService","org.projectforge.business.fibu.RechnungDO","org.projectforge.business.fibu.RechnungDao","org.projectforge.business.fibu.RechnungsPositionDO","org.projectforge.business.fibu.kost.Kost1Dao","org.projectforge.business.fibu.kost.Kost2ArtDao","org.projectforge.business.fibu.kost.Kost2Dao","org.projectforge.business.fibu.kost.KostZuweisungDO","org.projectforge.business.gantt.GanttChart","org.projectforge.business.gantt.GanttChartDao","org.projectforge.business.gantt.GanttTaskImpl","org.projectforge.business.humanresources.HRPlanningDO","org.projectforge.business.humanresources.HRPlanningDao","org.projectforge.business.humanresources.HRPlanningEntryDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.task.TaskDao","org.projectforge.business.task.TaskNode","org.projectforge.business.task.formatter.WicketTaskFormatter","org.projectforge.business.timesheet.TimesheetDao","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.business.user.GroupDao","org.projectforge.business.user.UserDao","org.projectforge.business.user.UserPrefDao","org.projectforge.excel.ExcelUtils","org.projectforge.framework.ToStringUtil","org.projectforge.framework.access.AccessDao","org.projectforge.framework.access.AccessEntryDO","org.projectforge.framework.access.GroupTaskAccessDO","org.projectforge.framework.jobs.AbstractJob","org.projectforge.framework.json.HibernateProxySerializer","org.projectforge.framework.persistence.api.BaseDao","org.projectforge.framework.persistence.database.HistoryMigrateService","org.projectforge.framework.persistence.database.ReindexerRegistry","org.projectforge.framework.persistence.database.ReindexerStrategy","org.projectforge.framework.persistence.entities.DefaultBaseDO","org.projectforge.framework.persistence.history.HibernateSearchDependentObjectsReindexer","org.projectforge.framework.persistence.history.HibernateSearchReindexer","org.projectforge.framework.persistence.jpa.impl.BaseDaoJpaAdapter","org.projectforge.framework.persistence.jpa.impl.LuceneServiceImpl","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.framework.persistence.user.entities.UserPrefEntryDO","org.projectforge.framework.persistence.user.entities.UserRightDO","org.projectforge.framework.persistence.xstream.ProxyIdRefMarshaller","org.projectforge.menu.builder.FavoritesMenuReaderWriter","org.projectforge.plugins.banking.BankingServicesRest","org.projectforge.plugins.datatransfer.DataTransferAreaDO","org.projectforge.plugins.datatransfer.rest.DataTransferAuditPageRest","org.projectforge.plugins.datatransfer.rest.DataTransferPageRest","org.projectforge.plugins.datatransfer.restPublic.DataTransferPublicAttachmentPageRest","org.projectforge.plugins.datatransfer.restPublic.DataTransferPublicPageRest","org.projectforge.plugins.datatransfer.restPublic.DataTransferPublicServicesRest","org.projectforge.plugins.eed.excelimport.EmployeeBillingExcelImporter","org.projectforge.plugins.eed.wicket.EmployeeBillingImportStoragePanel","org.projectforge.plugins.eed.wicket.EmployeeListEditPage","org.projectforge.plugins.ihk.IHKExporter","org.projectforge.plugins.memo.MemoDO","org.projectforge.plugins.merlin.MerlinTemplateDO","org.projectforge.plugins.merlin.rest.MerlinExecutionPageRest","org.projectforge.plugins.merlin.rest.MerlinVariablePageRest","org.projectforge.plugins.skillmatrix.SkillEntryDO","org.projectforge.rest.AddressImageServicesRest","org.projectforge.rest.AddressServicesRest","org.projectforge.rest.AddressViewPageRest","org.projectforge.rest.AttachmentPageRest","org.projectforge.rest.AttachmentsServicesRest","org.projectforge.rest.TimesheetFavoritesRest","org.projectforge.rest.TimesheetMultiSelectedPageRest","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.admin.LogViewerPageRest","org.projectforge.rest.calendar.CalEventPagesRest","org.projectforge.rest.calendar.CalendarFilterServicesRest","org.projectforge.rest.calendar.CalendarSettingsPageRest","org.projectforge.rest.calendar.TeamEventPagesRest","org.projectforge.rest.config.IdObjectDeserializer","org.projectforge.rest.config.JacksonConfiguration","org.projectforge.rest.core.AbstractPagesRest","org.projectforge.rest.dvelop.DvelopClient","org.projectforge.rest.fibu.kost.Kost2ArtPagesRest","org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.rest.json.UISelectTypeSerializer","org.projectforge.rest.my2fa.My2FAServicesRest","org.projectforge.rest.my2fa.My2FASetupPageRest","org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.rest.orga.VisitorbookPagesRest","org.projectforge.rest.scripting.MyScriptExecutePageRest","org.projectforge.rest.scripting.ScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest","org.projectforge.rest.task.TaskFavoritesRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.security.dto.WebAuthnPublicKeyCredentialCreationOptions","org.projectforge.security.webauthn.WebAuthnEntryDao","org.projectforge.ui.UISelect","org.projectforge.web.OrphanedLinkFilter","org.projectforge.web.fibu.CustomerEditForm","org.projectforge.web.fibu.Kost2ArtEditForm","org.projectforge.web.fibu.Kost2ArtListPage","org.projectforge.web.fibu.NewCustomerSelectPanel","org.projectforge.web.fibu.NewProjektSelectPanel","org.projectforge.web.gantt.GanttTreeTableNode","org.projectforge.web.orga.VisitorbookListPage","org.projectforge.web.user.NewGroupSelectPanel","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.components.TabPanel"],"usedInFiles":["./projectforge-rest/src/main/kotlin/org/projectforge/rest/json/Deserializers.kt"]}, + {"i18nKey":"id","bundleName":"I18nResources","translation":"Id","translationDE":"Id","usedInClasses":["org.apache.batik.util.XMLConstants","org.projectforge.business.address.AddressExport","org.projectforge.business.address.PersonalAddressDao","org.projectforge.business.book.BookDao","org.projectforge.business.fibu.AuftragDao","org.projectforge.business.fibu.EingangsrechnungDO","org.projectforge.business.fibu.EingangsrechnungsPositionDO","org.projectforge.business.fibu.EmployeeDO","org.projectforge.business.fibu.EmployeeSalaryDao","org.projectforge.business.fibu.InvoiceService","org.projectforge.business.fibu.RechnungDO","org.projectforge.business.fibu.RechnungDao","org.projectforge.business.fibu.RechnungsPositionDO","org.projectforge.business.fibu.kost.Kost1Dao","org.projectforge.business.fibu.kost.Kost2ArtDao","org.projectforge.business.fibu.kost.Kost2Dao","org.projectforge.business.fibu.kost.KostZuweisungDO","org.projectforge.business.gantt.GanttChart","org.projectforge.business.gantt.GanttChartDao","org.projectforge.business.gantt.GanttTaskImpl","org.projectforge.business.humanresources.HRPlanningDO","org.projectforge.business.humanresources.HRPlanningDao","org.projectforge.business.humanresources.HRPlanningEntryDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.task.TaskDao","org.projectforge.business.task.TaskNode","org.projectforge.business.task.formatter.WicketTaskFormatter","org.projectforge.business.timesheet.TimesheetDao","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.business.user.GroupDao","org.projectforge.business.user.UserDao","org.projectforge.business.user.UserPrefDao","org.projectforge.excel.ExcelUtils","org.projectforge.framework.ToStringUtil","org.projectforge.framework.access.AccessDao","org.projectforge.framework.access.AccessEntryDO","org.projectforge.framework.access.GroupTaskAccessDO","org.projectforge.framework.jobs.AbstractJob","org.projectforge.framework.json.HibernateProxySerializer","org.projectforge.framework.persistence.api.BaseDao","org.projectforge.framework.persistence.database.HistoryMigrateService","org.projectforge.framework.persistence.database.ReindexerRegistry","org.projectforge.framework.persistence.database.ReindexerStrategy","org.projectforge.framework.persistence.entities.DefaultBaseDO","org.projectforge.framework.persistence.history.HibernateSearchDependentObjectsReindexer","org.projectforge.framework.persistence.history.HibernateSearchReindexer","org.projectforge.framework.persistence.jpa.impl.BaseDaoJpaAdapter","org.projectforge.framework.persistence.jpa.impl.LuceneServiceImpl","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.framework.persistence.user.entities.UserPrefEntryDO","org.projectforge.framework.persistence.user.entities.UserRightDO","org.projectforge.framework.persistence.xstream.ProxyIdRefMarshaller","org.projectforge.menu.builder.FavoritesMenuReaderWriter","org.projectforge.plugins.banking.BankingServicesRest","org.projectforge.plugins.datatransfer.DataTransferAreaDO","org.projectforge.plugins.datatransfer.rest.DataTransferAuditPageRest","org.projectforge.plugins.datatransfer.rest.DataTransferPageRest","org.projectforge.plugins.datatransfer.restPublic.DataTransferPublicAttachmentPageRest","org.projectforge.plugins.datatransfer.restPublic.DataTransferPublicPageRest","org.projectforge.plugins.datatransfer.restPublic.DataTransferPublicServicesRest","org.projectforge.plugins.eed.excelimport.EmployeeBillingExcelImporter","org.projectforge.plugins.eed.wicket.EmployeeBillingImportStoragePanel","org.projectforge.plugins.eed.wicket.EmployeeListEditPage","org.projectforge.plugins.ihk.IHKExporter","org.projectforge.plugins.memo.MemoDO","org.projectforge.plugins.merlin.MerlinTemplateDO","org.projectforge.plugins.merlin.rest.MerlinExecutionPageRest","org.projectforge.plugins.merlin.rest.MerlinVariablePageRest","org.projectforge.plugins.skillmatrix.SkillEntryDO","org.projectforge.rest.AddressImageServicesRest","org.projectforge.rest.AddressServicesRest","org.projectforge.rest.AddressViewPageRest","org.projectforge.rest.AttachmentPageRest","org.projectforge.rest.AttachmentsServicesRest","org.projectforge.rest.TimesheetFavoritesRest","org.projectforge.rest.TimesheetMultiSelectedPageRest","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.admin.LogViewerPageRest","org.projectforge.rest.calendar.CalEventPagesRest","org.projectforge.rest.calendar.CalendarFilterServicesRest","org.projectforge.rest.calendar.CalendarSettingsPageRest","org.projectforge.rest.calendar.TeamEventPagesRest","org.projectforge.rest.config.IdObjectDeserializer","org.projectforge.rest.config.JacksonConfiguration","org.projectforge.rest.core.AbstractPagesRest","org.projectforge.rest.dvelop.DvelopClient","org.projectforge.rest.fibu.kost.Kost2ArtPagesRest","org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.rest.json.UISelectTypeSerializer","org.projectforge.rest.my2fa.My2FAServicesRest","org.projectforge.rest.my2fa.My2FASetupPageRest","org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.rest.orga.VisitorbookPagesRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.rest.scripting.MyScriptExecutePageRest","org.projectforge.rest.scripting.ScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest","org.projectforge.rest.task.TaskFavoritesRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.security.dto.WebAuthnPublicKeyCredentialCreationOptions","org.projectforge.security.webauthn.WebAuthnEntryDao","org.projectforge.ui.UISelect","org.projectforge.web.OrphanedLinkFilter","org.projectforge.web.fibu.CustomerEditForm","org.projectforge.web.fibu.Kost2ArtEditForm","org.projectforge.web.fibu.Kost2ArtListPage","org.projectforge.web.fibu.NewCustomerSelectPanel","org.projectforge.web.fibu.NewProjektSelectPanel","org.projectforge.web.gantt.GanttTreeTableNode","org.projectforge.web.orga.VisitorbookListPage","org.projectforge.web.user.NewGroupSelectPanel","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.components.TabPanel"],"usedInFiles":["./projectforge-rest/src/main/kotlin/org/projectforge/rest/json/Deserializers.kt"]}, {"i18nKey":"imageFile","bundleName":"I18nResources","translation":"Image","translationDE":"Bild","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"import","bundleName":"I18nResources","translation":"Import","translationDE":"Importieren","usedInClasses":["org.projectforge.business.scripting.KotlinScriptExecutor","org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.web.admin.SetupImportForm","org.projectforge.web.fibu.ReportObjectivesForm","org.projectforge.web.teamcal.admin.TeamCalEditPage"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/admin/SetupPage.html"]}, {"i18nKey":"import.confirmMessage","bundleName":"I18nResources","translation":"Would you like to import the selected entries now? This option isn't undoable.","translationDE":"Sollen nun alle ausgewählten Einträge importiert werden? Diese Aktion kann nicht rückgängig gemacht werden.","usedInClasses":["org.projectforge.rest.importer.AbstractImportPageRest"],"usedInFiles":[]}, @@ -1697,6 +1697,7 @@ {"i18nKey":"menu.phoneCall","bundleName":"I18nResources","translation":"Direct call","translationDE":"Direktwahl","usedInClasses":["org.projectforge.menu.builder.MenuItemDefId","org.projectforge.rest.AddressPagesRest"],"usedInFiles":[]}, {"i18nKey":"menu.pluginAdmin","bundleName":"I18nResources","translation":"Plugins","translationDE":"Plugins","usedInClasses":["org.projectforge.menu.builder.MenuItemDefId"],"usedInFiles":[]}, {"i18nKey":"menu.plugins.teamcal","bundleName":"I18nResources","translation":"List of calendars","translationDE":"Kalenderliste","usedInClasses":["org.projectforge.menu.builder.MenuItemDefId","org.projectforge.rest.calendar.CalendarFilterServicesRest"],"usedInFiles":[]}, + {"i18nKey":"menu.poll","bundleName":"I18nResources","translation":"Polls","translationDE":"Umfragen","usedInClasses":["org.projectforge.menu.builder.MenuItemDefId"],"usedInFiles":[]}, {"i18nKey":"menu.projectDocumentation","bundleName":"I18nResources","translation":"Project docs","translationDE":"Project docs","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"menu.projectmanagement","bundleName":"I18nResources","translation":"Project management","translationDE":"Projektmanagement","usedInClasses":["org.projectforge.menu.builder.MenuItemDefId"],"usedInFiles":[]}, {"i18nKey":"menu.reindexAllDatabaseEntries","bundleName":"I18nResources","translation":"Re-build whole search index","translationDE":"Suchindex voll indizieren","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest","org.projectforge.web.wicket.AbstractReindexTopRightMenu"],"usedInFiles":[]}, @@ -1745,7 +1746,7 @@ {"i18nKey":"new","bundleName":"I18nResources","translation":"New","translationDE":"Neu","usedInClasses":["org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.web.wicket.AbstractListPage"],"usedInFiles":[]}, {"i18nKey":"next","bundleName":"I18nResources","translation":"Next","translationDE":"Weiter","usedInClasses":["org.projectforge.plugins.datatransfer.rest.DataTransferPersonalBoxPageRest","org.projectforge.ui.UIAgGrid","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, {"i18nKey":"nickname","bundleName":"I18nResources","translation":"Nickname","translationDE":"Rufname","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.plugins.merlin.rest.MerlinExecutionPageRest","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, - {"i18nKey":"no","bundleName":"I18nResources","translation":"No","translationDE":"Nein","usedInClasses":["org.projectforge.business.vacation.service.VacationSendMailService","org.projectforge.rest.dto.Vacation"],"usedInFiles":["./projectforge-business/src/main/kotlin/org/projectforge/framework/i18n/I18n.kt"]}, + {"i18nKey":"no","bundleName":"I18nResources","translation":"No","translationDE":"Nein","usedInClasses":["org.projectforge.business.vacation.service.VacationSendMailService","org.projectforge.rest.dto.Vacation","org.projectforge.rest.poll.PollPageRest"],"usedInFiles":["./projectforge-business/src/main/kotlin/org/projectforge/framework/i18n/I18n.kt"]}, {"i18nKey":"notEnded","bundleName":"I18nResources","translation":"not ended","translationDE":"nicht beendet","usedInClasses":["org.projectforge.business.fibu.ProjektFilter","org.projectforge.business.fibu.kost.KostFilter","org.projectforge.web.fibu.Kost1ListForm","org.projectforge.web.fibu.Kost2ListForm","org.projectforge.web.fibu.ProjektListForm"],"usedInFiles":[]}, {"i18nKey":"notLoggedIn","bundleName":"I18nResources","translation":"Not logged in.","translationDE":"Nicht angemeldet","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"notVisible","bundleName":"I18nResources","translation":"not visible","translationDE":"nicht sichtbar","usedInClasses":["org.projectforge.business.utils.BaseFormatter"],"usedInFiles":[]}, @@ -2010,15 +2011,68 @@ {"i18nKey":"plugins.teamcal.selectTemplate","bundleName":"I18nResources","translation":"Choose filter template","translationDE":"Filterschablone auswählen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.subscription","bundleName":"I18nResources","translation":"Subscription","translationDE":"Abonnement","usedInClasses":["org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.calendar.CalendarSubscriptionInfoPageRest","org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage"],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.subscription.timesheets","bundleName":"I18nResources","translation":"You can subscribe your time sheets in your personal calendar (e. g. Apple iCal oder Microsoft Outlook).","translationDE":"Über diese URL können Sie Ihre Zeitberichte in Ihrem persönlichen Kalender abonnieren (z. B. Apple iCal oder Microsoft Outlook).","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"plugins.teamcal.subscription.tooltip","bundleName":"I18nResources","translation":"You can subscribe this calendar in your personal calendar (e. g. Apple iCal oder Microsoft Outlook).","translationDE":"Über diese URL können Sie den Kalender in Ihrem persönlichen Kalender abonnieren (z. B. Apple iCal oder Microsoft Outlook).","usedInClasses":["org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage"],"usedInFiles":[]}, + {"i18nKey":"plugins.teamcal.subscription.tooltip","bundleName":"I18nResources","translation":"You can subscribe this calendar in your personal calendar (e. g. Apple iCal oder Microsoft Outlook).","translationDE":"Über diese URL können Sie den Kalender in Ihrem persönlichen Kalender abonnieren (z. B. Apple iCal oder Microsoft Outlook).","usedInClasses":["org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage"],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.switchToTeamEventButton","bundleName":"I18nResources","translation":"Switch to events","translationDE":"In Termin umwandeln","usedInClasses":["org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.teamcal.integration.TeamcalTimesheetPluginComponentHook"],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.switchToTimesheetButton","bundleName":"I18nResources","translation":"Switch to time sheet","translationDE":"In Zeitbuchung umwandeln","usedInClasses":["org.projectforge.rest.calendar.CalEventPagesRest","org.projectforge.rest.calendar.TeamEventPagesRest","org.projectforge.web.teamcal.event.TeamEventEditPage"],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.timeSheetCalendar","bundleName":"I18nResources","translation":"Time sheets","translationDE":"Zeitbuchungen","usedInClasses":["org.projectforge.web.teamcal.dialog.TeamCalFilterDialog"],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.title","bundleName":"I18nResources","translation":"Title","translationDE":"Titel","usedInClasses":["org.projectforge.business.teamcal.admin.model.TeamCalDO","org.projectforge.rest.TeamCalPagesRest","org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage"],"usedInFiles":[]}, - {"i18nKey":"plugins.teamcal.title.add","bundleName":"I18nResources","translation":"Add calendar","translationDE":"Kalender hinzufügen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"plugins.teamcal.title.add","bundleName":"I18nResources","translation":"Add calendar","translationDE":"Kalender hinzufügen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.title.edit","bundleName":"I18nResources","translation":"Edit team calendar","translationDE":"Team-Kalender bearbeiten","usedInClasses":["org.projectforge.web.teamcal.admin.TeamCalEditPage","org.projectforge.web.teamcal.admin.TeamCalListPage"],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.title.heading","bundleName":"I18nResources","translation":"Calendar","translationDE":"Kalender","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"plugins.teamcal.title.list","bundleName":"I18nResources","translation":"List of calendars","translationDE":"Kalenderliste","usedInClasses":["org.projectforge.web.teamcal.admin.TeamCalEditPage","org.projectforge.web.teamcal.admin.TeamCalListPage"],"usedInFiles":[]}, + {"i18nKey":"poll","bundleName":"I18nResources","translation":"Poll","translationDE":"Umfrage","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.menu.builder.MenuItemDefId"],"usedInFiles":[]}, + {"i18nKey":"poll.access","bundleName":"I18nResources","translation":"Access","translationDE":"Zugriff","usedInClasses":["org.projectforge.business.poll.filter.PollAssignment"],"usedInFiles":[]}, + {"i18nKey":"poll.answer","bundleName":"I18nResources","translation":"Answer","translationDE":"Antwort","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.assignment","bundleName":"I18nResources","translation":"Assignment","translationDE":"Zuordnung","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.attendee","bundleName":"I18nResources","translation":"Attendee","translationDE":"Teilnehmer:in","usedInClasses":["org.projectforge.business.poll.filter.PollAssignment"],"usedInFiles":[]}, + {"i18nKey":"poll.attendees","bundleName":"I18nResources","translation":"Attendees","translationDE":"Teilnehmer:innen","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.button.addQuestion","bundleName":"I18nResources","translation":"Add own question","translationDE":"Eigene Frage hinzufügen","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.button.finish","bundleName":"I18nResources","translation":"Finish Poll","translationDE":"Umfrage beenden","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.button.micromataTemplate","bundleName":"I18nResources","translation":"Use Micromata Template","translationDE":"Micromata Template verwenden","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.confirmation.creation","bundleName":"I18nResources","translation":"Do you really want to create the poll? You won't be able to edit the questions afterwards.Also make sure to add attendees for your poll.","translationDE":"Möchtest du die Umfrage wirklich erstellen? Du kannst die Fragen danach nicht mehr bearbeiten.Stelle ebenfalls sicher, dass du Teilnehmer für deine Umfrage hinzugefügt hast.","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.confirmation.deleteAnswer","bundleName":"I18nResources","translation":"Do you really want to delete this answer?","translationDE":"Möchtest du diese Antwort wirklich löschen?","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.confirmation.deleteQuestion","bundleName":"I18nResources","translation":"Do you really want to delete this question?","translationDE":"Möchtest du diese Frage wirklich löschen?","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.confirmation.finish","bundleName":"I18nResources","translation":"Do you really want to finish this Poll?","translationDE":"Willst du die Umfrage wirklich beenden? ","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.date","bundleName":"I18nResources","translation":"Date","translationDE":"Datum","usedInClasses":["org.projectforge.business.poll.PollDO"],"usedInFiles":[]}, + {"i18nKey":"poll.deadline","bundleName":"I18nResources","translation":"Deadline","translationDE":"Antwortfrist","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.delegationAnswers","bundleName":"I18nResources","translation":"Answers of ","translationDE":"Antworten von ","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.description","bundleName":"I18nResources","translation":"Description","translationDE":"Beschreibung","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.error.oneQuestionRequired","bundleName":"I18nResources","translation":"At least one question is required.","translationDE":"Mindestens eine Frage ist erforderlich.","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.exception.noAttendee","bundleName":"I18nResources","translation":"This user is not part of the poll.","translationDE":"Dieser Nutzer ist nicht Teil der Umfrage.","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.export.response.poll","bundleName":"I18nResources","translation":"Export results","translationDE":"Ergebnisse exportieren","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.finished","bundleName":"I18nResources","translation":"Finished","translationDE":"Beendet","usedInClasses":["org.projectforge.business.poll.filter.PollState"],"usedInFiles":[]}, + {"i18nKey":"poll.fullAccessGroups","bundleName":"I18nResources","translation":"Full Access Groups","translationDE":"Gruppen mit Vollzugriff","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.fullAccessUsers","bundleName":"I18nResources","translation":"Full Access User","translationDE":"Benutzer:innen mit Vollzugriff","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.groupAttendees","bundleName":"I18nResources","translation":"Attendee Groups","translationDE":"Teilnehmergruppen","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.guide","bundleName":"I18nResources","translation":"Poll Guide","translationDE":"Anleitung","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.infopage","bundleName":"I18nResources","translation":"Info Page","translationDE":"Infoseite","usedInClasses":["org.projectforge.rest.poll.PollInfoPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.location","bundleName":"I18nResources","translation":"Location","translationDE":"Ort","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.mail.ended.content","bundleName":"I18nResources","translation":"

Dear Attendees,

We wanted to let you know that the poll \"{0}\" created by {1} has now ended. Thank you to everyone who participated and provided valuable input.

If you missed the deadline to submit your responses, we encourage you to still share your thoughts with us. While we may not be able to include your responses in the official results, your feedback is still valuable for future polls.

Thank you again for your participation.

Best regards,

{1}

","translationDE":"

Liebe Teilnehmerinnen und Teilnehmer,

wir möchten Sie darüber informieren, dass die Umfrage \"{0}\", erstellt von {1}, nun abgeschlossen ist. Vielen Dank an alle, die teilgenommen und wertvolles Feedback gegeben haben.

Falls Sie den Einsendeschluss verpasst haben, möchten wir Sie dennoch ermutigen, uns Ihre Gedanken mitzuteilen. Auch wenn wir Ihre Antworten möglicherweise nicht in den offiziellen Ergebnissen berücksichtigen können, ist Ihr Feedback dennoch wertvoll für zukünftige Umfragen und Initiativen.

Nochmals vielen Dank für Ihre Teilnahme.


Freundliche Grüße,

{1}

","usedInClasses":["org.projectforge.rest.poll.PollCronJobs"],"usedInFiles":[]}, + {"i18nKey":"poll.mail.ended.subject","bundleName":"I18nResources","translation":"Poll ended","translationDE":"Umfrage beendet","usedInClasses":["org.projectforge.rest.poll.PollCronJobs"],"usedInFiles":[]}, + {"i18nKey":"poll.mail.endingSoon.content","bundleName":"I18nResources","translation":"

Dear Attendees,

This is a friendly reminder that the poll \"{0}\" created by {1} is ending soon, on {2}. Please make sure to submit your responses before the deadline.

If you have not yet had a chance to participate, please take a few moments to do so before the poll closes. Your input is important and valued.

{3}

Thank you for your attention, and have a great day!

Best regards,

{1}

","translationDE":"

Liebe Teilnehmerinnen und Teilnehmer,

wir möchten Sie daran erinnern, dass die Umfrage \"{0}\", erstellt von {1}, bald endet, nämlich am {2}. Bitte achten Sie darauf, Ihre Antworten vor dem Ablaufdatum einzureichen.

Falls Sie noch nicht die Gelegenheit hatten, an der Umfrage teilzunehmen, nehmen Sie sich bitte einen Moment Zeit, um dies zu tun, bevor die Umfrage geschlossen wird. Ihre Meinung ist wichtig und wertvoll.

{3}

Vielen Dank für Ihre Aufmerksamkeit und einen schönen Tag!


Freundliche Grüße,

{1}

","usedInClasses":["org.projectforge.rest.poll.PollCronJobs"],"usedInFiles":[]}, + {"i18nKey":"poll.mail.endingSoon.subject","bundleName":"I18nResources","translation":"Poll ending in {0} days","translationDE":"Umfrage endet in {0} Tagen","usedInClasses":["org.projectforge.rest.poll.PollCronJobs"],"usedInFiles":[]}, + {"i18nKey":"poll.mail.update.content","bundleName":"I18nResources","translation":"

Dear Attendees,

We wanted to let you know that the poll \"{0}\" was edited recently.

If you already submitted your answers, you should check, if there were any major changes made.

Thank you again for your participation.

Best regards,

{1}

","translationDE":"

Liebe Teilnehmerinnen und Teilnehmer,

Wir möchten Ihnen mitteilen, dass die Umfrage \"{0}\" kürzlich bearbeitet wurde.

Falls Sie bereits Ihre Antworten eingereicht haben, sollten Sie überprüfen, ob wesentliche Änderungen vorgenommen wurden.

Nochmals vielen Dank für Ihre Teilnahme.

Freundliche Grüße,

{1}

","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.mail.update.subject","bundleName":"I18nResources","translation":"Poll was edited","translationDE":"Umfrage wurde bearbeitet","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.other","bundleName":"I18nResources","translation":"Other","translationDE":"Andere","usedInClasses":["org.projectforge.business.poll.filter.PollAssignment"],"usedInFiles":[]}, + {"i18nKey":"poll.owner","bundleName":"I18nResources","translation":"Owner","translationDE":"Eigentümer:in","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.business.poll.filter.PollAssignment","org.projectforge.rest.poll.PollPageRest","org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.popup.closed","bundleName":"I18nResources","translation":"The poll was already closed.","translationDE":"Umfrage wurde bereits beendet","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"poll.question","bundleName":"I18nResources","translation":"Question","translationDE":"Frage","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.question.textQuestion","bundleName":"I18nResources","translation":"Text Question","translationDE":"Textfrage","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.questionType","bundleName":"I18nResources","translation":"Question Type","translationDE":"Fragen Typ","usedInClasses":["org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.respond","bundleName":"I18nResources","translation":"Send responses","translationDE":"Antworten abschicken","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.response.mail.update.content","bundleName":"I18nResources","translation":"

Dear {0},

I wanted to inform you that Person {2} has updated their answer to Poll {1}.

If you were not notified about this,

I recommend reaching out to the person directly or adjusting your results accordingly.

You can modify your response until \"{3}\".

Best regards,

{2}

","translationDE":"

Dear {0},

I wanted to inform you that Person {2} has updated their answer to Poll {1}.

If you were not notified about this,

I recommend reaching out to the person directly or adjusting your results accordingly.

You can modify your response until \"{3}\".

Best regards,

{2}

","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.response.mail.update.subject","bundleName":"I18nResources","translation":"Response was edited by {0}","translationDE":"Response was edited by {0}","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.response.page","bundleName":"I18nResources","translation":"Poll Response Page","translationDE":"Seite zur Umfrageantwort","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"poll.response.title","bundleName":"I18nResources","translation":"Poll Response Page","translationDE":"Seite zur Umfrageantwort","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.running","bundleName":"I18nResources","translation":"Running","translationDE":"Aktiv","usedInClasses":["org.projectforge.business.poll.filter.PollState"],"usedInFiles":[]}, + {"i18nKey":"poll.selectUser","bundleName":"I18nResources","translation":"Select user","translationDE":"Nutzer auswählen","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.state","bundleName":"I18nResources","translation":"State","translationDE":"Status","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.title","bundleName":"I18nResources","translation":"Title","translationDE":"Titel","usedInClasses":["org.projectforge.business.poll.PollDO","org.projectforge.rest.poll.PollPageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.title.add","bundleName":"I18nResources","translation":"Create new Poll","translationDE":"Neue Umfrage erstellen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"poll.title.edit","bundleName":"I18nResources","translation":"Edit Poll","translationDE":"Umfrage bearbeiten","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.title.list","bundleName":"I18nResources","translation":"Polls","translationDE":"Umfragen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"poll.userDelegation","bundleName":"I18nResources","translation":"User delegation","translationDE":"Für andere Nutzer abstimmen","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, + {"i18nKey":"poll.yourAnswers","bundleName":"I18nResources","translation":"Your answers","translationDE":"Deine Antworten","usedInClasses":["org.projectforge.rest.poll.ResponsePageRest"],"usedInFiles":[]}, {"i18nKey":"preview","bundleName":"I18nResources","translation":"Preview","translationDE":"Vorschau","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"printView","bundleName":"I18nResources","translation":"print view","translationDE":"Druckansicht","usedInClasses":["org.projectforge.rest.AddressPagesRest","org.projectforge.web.address.AddressListPage"],"usedInFiles":[]}, {"i18nKey":"priority","bundleName":"I18nResources","translation":"Priority","translationDE":"Priorität","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.plugins.todo.ToDoDO","org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.plugins.todo.rest.ToDoPagesRest","org.projectforge.rest.hr.HRPlanningListPagesRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.humanresources.HRPlanningListPage","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder"],"usedInFiles":["./projectforge-business/src/main/resources/mail/todoChangeNotification.html"]}, @@ -2030,10 +2084,10 @@ {"i18nKey":"priority.without","bundleName":"I18nResources","translation":"without","translationDE":"ohne","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"projectmanagement.personDays","bundleName":"I18nResources","translation":"Person days","translationDE":"Personentage","usedInClasses":["org.projectforge.business.fibu.AuftragsPositionDO","org.projectforge.rest.fibu.AuftragPagesRest","org.projectforge.web.fibu.AuftragEditForm"],"usedInFiles":[]}, {"i18nKey":"projectmanagement.personDays.short","bundleName":"I18nResources","translation":"pd","translationDE":"PT","usedInClasses":["org.projectforge.business.fibu.OrderExport","org.projectforge.rest.task.Consumption","org.projectforge.web.fibu.AuftragListPage","org.projectforge.web.fibu.OrderPositionsPanel","org.projectforge.web.task.TaskListPage"],"usedInFiles":[]}, - {"i18nKey":"question.deleteQuestion","bundleName":"I18nResources","translation":"Do your really want to delete this object finally?","translationDE":"Soll das Objekt wirklich unwiderruflich gelöscht werden?","usedInClasses":["org.projectforge.ui.UIButton","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.WicketUtils"],"usedInFiles":[]}, - {"i18nKey":"question.forceDeleteQuestion","bundleName":"I18nResources","translation":"ATTENTION!!! Do you really want to destroy this object including all history entries? This option is irrevocable!!!!!","translationDE":"ACHTUNG!!! Soll das Object tatsächlich uwiderruflich gelöscht werden? Es werden auch alle Einträge aus der Änderungshistorie zu diesem Object unwiderruflich gelöscht!!!!!!","usedInClasses":["org.projectforge.ui.UIButton"],"usedInFiles":[]}, - {"i18nKey":"question.markAsDeletedQuestion","bundleName":"I18nResources","translation":"Do you want to mark this object as deleted?","translationDE":"Soll das Objekt als gelöscht markiert werden?","usedInClasses":["org.projectforge.ui.UIButton","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.WicketUtils"],"usedInFiles":[]}, - {"i18nKey":"question.massUpdateQuestion","bundleName":"I18nResources","translation":"Do you really want to update all objects now?","translationDE":"Sollen nun alle Objekte geändert werden?","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"question.deleteQuestion","bundleName":"I18nResources","translation":"Do your really want to delete this object finally?","translationDE":"Soll das Objekt wirklich unwiderruflich gelöscht werden?","usedInClasses":["org.projectforge.ui.UIButton","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.WicketUtils"],"usedInFiles":[]}, + {"i18nKey":"question.forceDeleteQuestion","bundleName":"I18nResources","translation":"ATTENTION!!! Do you really want to destroy this object including all history entries? This option is irrevocable!!!!!","translationDE":"ACHTUNG!!! Soll das Object tatsächlich uwiderruflich gelöscht werden? Es werden auch alle Einträge aus der Änderungshistorie zu diesem Object unwiderruflich gelöscht!!!!!!","usedInClasses":["org.projectforge.ui.UIButton"],"usedInFiles":[]}, + {"i18nKey":"question.markAsDeletedQuestion","bundleName":"I18nResources","translation":"Do you want to mark this object as deleted?","translationDE":"Soll das Objekt als gelöscht markiert werden?","usedInClasses":["org.projectforge.ui.UIButton","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.WicketUtils"],"usedInFiles":[]}, + {"i18nKey":"question.massUpdateQuestion","bundleName":"I18nResources","translation":"Do you really want to update all objects now?","translationDE":"Sollen nun alle Objekte geändert werden?","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"quickselect","bundleName":"I18nResources","translation":"Quick-select","translationDE":"Schnellauswahl","usedInClasses":["org.projectforge.web.task.TaskSelectPanel"],"usedInFiles":[]}, {"i18nKey":"recalculate","bundleName":"I18nResources","translation":"Recalculate","translationDE":"Neu berechnen","usedInClasses":["org.projectforge.rest.VacationAccountPageRest","org.projectforge.web.fibu.RechnungCostEditTablePanel","org.projectforge.web.humanresources.HRPlanningEditForm"],"usedInFiles":[]}, {"i18nKey":"recursive","bundleName":"I18nResources","translation":"recursive","translationDE":"rekursiv","usedInClasses":["org.projectforge.business.timesheet.TimesheetFilter","org.projectforge.framework.access.GroupTaskAccessDO","org.projectforge.web.access.AccessEditForm","org.projectforge.web.access.AccessListPage","org.projectforge.web.timesheet.TimesheetListForm"],"usedInFiles":[]}, @@ -2047,25 +2101,25 @@ {"i18nKey":"resumption","bundleName":"I18nResources","translation":"Resumption","translationDE":"Wiedervorlage","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"save","bundleName":"I18nResources","translation":"Save","translationDE":"Speichern","usedInClasses":["org.projectforge.model.rest.RestPaths","org.projectforge.plugins.eed.wicket.EmployeeListEditForm","org.projectforge.rest.calendar.CalendarSettingsPageRest","org.projectforge.ui.LayoutUtils","org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.wicket.flowlayout.IconType"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/gantt/GanttChartEditTreeTablePanel.html"]}, {"i18nKey":"scripting.download.filename","bundleName":"I18nResources","translation":"Result file","translationDE":"Ergbnisdatei","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"scripting.download.filename.additional","bundleName":"I18nResources","translation":"Download only available for a few minutes: until {0}.","translationDE":"Download nur wenige Minuten verfügbar: bis {0}.","usedInClasses":["org.projectforge.rest.core.DownloadFileSupport"],"usedInFiles":[]}, - {"i18nKey":"scripting.download.filename.info","bundleName":"I18nResources","translation":"File generated by last script run.","translationDE":"Downloaddatei der letzten Scriptausführung.","usedInClasses":["org.projectforge.rest.scripting.AbstractScriptExecutePageRest"],"usedInFiles":[]}, + {"i18nKey":"scripting.download.filename.additional","bundleName":"I18nResources","translation":"Download only available for a few minutes: until {0}.","translationDE":"Download nur wenige Minuten verfügbar: bis {0}.","usedInClasses":["org.projectforge.rest.core.DownloadFileSupport"],"usedInFiles":[]}, + {"i18nKey":"scripting.download.filename.info","bundleName":"I18nResources","translation":"File generated by last script run.","translationDE":"Downloaddatei der letzten Scriptausführung.","usedInClasses":["org.projectforge.rest.scripting.AbstractScriptExecutePageRest"],"usedInFiles":[]}, {"i18nKey":"scripting.myScript.list","bundleName":"I18nResources","translation":"My scripts","translationDE":"Meine Scripte","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"scripting.script","bundleName":"I18nResources","translation":"Script","translationDE":"Script","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"scripting.script.availableVariables","bundleName":"I18nResources","translation":"Availabe variables","translationDE":"Verfügbare Variablen","usedInClasses":["org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.description.tooltip","bundleName":"I18nResources","translation":"Markdown format is supported.","translationDE":"Markdown-Format wird unterstützt.","usedInClasses":["org.projectforge.business.scripting.ScriptDO"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.availableVariables","bundleName":"I18nResources","translation":"Available variables","translationDE":"Verfügbare Variablen","usedInClasses":["org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.description.tooltip","bundleName":"I18nResources","translation":"Markdown format is supported.","translationDE":"Markdown-Format wird unterstützt.","usedInClasses":["org.projectforge.business.scripting.ScriptDO"],"usedInFiles":[]}, {"i18nKey":"scripting.script.downloadBackups","bundleName":"I18nResources","translation":"Download backups","translationDE":"Download Backups","usedInClasses":["org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, {"i18nKey":"scripting.script.downloadEffectiveScript","bundleName":"I18nResources","translation":"Download effective script","translationDE":"Download Effektivscript","usedInClasses":["org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.downloadEffectiveScript.info","bundleName":"I18nResources","translation":"The effective script is the script with resolved includes etc. executed by the scripting engine.","translationDE":"Das Effektivscript ist das Script mit aufgelösten Include-Dateien etc., welches so von der Scripting-Engine so ausgeführt wird.","usedInClasses":["org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.editForm.file.tooltip","bundleName":"I18nResources","translation":"Within the script the file is available through 'script.file' and the name of the file through 'script.filename'. This is only for backward compability for older scripts, generated by classical version.","translationDE":"Die Datei ist im Script über 'script.file' und der Dateiname über 'script.filename' erreichbar. Diese Datei ist aus Abwährtskompatibiltätsgründen noch nutzbar für ältere Scripte.","usedInClasses":["org.projectforge.business.scripting.ScriptDO"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.downloadEffectiveScript.info","bundleName":"I18nResources","translation":"The effective script is the script with resolved includes etc. executed by the scripting engine.","translationDE":"Das Effektivscript ist das Script mit aufgelösten Include-Dateien etc., welches so von der Scripting-Engine so ausgeführt wird.","usedInClasses":["org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.editForm.file.tooltip","bundleName":"I18nResources","translation":"Within the script the file is available through 'script.file' and the name of the file through 'script.filename'. This is only for backward compability for older scripts, generated by classical version.","translationDE":"Die Datei ist im Script über 'script.file' und der Dateiname über 'script.filename' erreichbar. Diese Datei ist aus Abwährtskompatibiltätsgründen noch nutzbar für ältere Scripte.","usedInClasses":["org.projectforge.business.scripting.ScriptDO"],"usedInFiles":[]}, {"i18nKey":"scripting.script.error.notFound","bundleName":"I18nResources","translation":"Script not found.","translationDE":"Script not found.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"scripting.script.examples","bundleName":"I18nResources","translation":"Examples","translationDE":"Beispiele","usedInClasses":["org.projectforge.rest.scripting.ScriptExecutePageRest"],"usedInFiles":[]}, {"i18nKey":"scripting.script.executableByGroups","bundleName":"I18nResources","translation":"Allowed groups","translationDE":"Berechtigte Gruppen","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.executableByGroups.info","bundleName":"I18nResources","translation":"Users of these groups are allowed to execute this script (but they can't see or modify the sources of this script).","translationDE":"Angehörige dieser Gruppen dürfen dieses Script ausführen (nicht einsehen oder ändern).","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.executableByGroups.info","bundleName":"I18nResources","translation":"Users of these groups are allowed to execute this script (but they can't see or modify the sources of this script).","translationDE":"Angehörige dieser Gruppen dürfen dieses Script ausführen (nicht einsehen oder ändern).","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, {"i18nKey":"scripting.script.executableByUsers","bundleName":"I18nResources","translation":"Allowed users","translationDE":"Berechtigte Benutzer:innen","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.executableByUsers.info","bundleName":"I18nResources","translation":"These users are allowed to execute this script (but they can't see or modify the sources of this script).","translationDE":"Diese dürfen dieses Script ausführen (nicht einsehen oder ändern).","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.execute","bundleName":"I18nResources","translation":"Execute script","translationDE":"Script ausführen","usedInClasses":["org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.executeAsUser","bundleName":"I18nResources","translation":"Execute as user","translationDE":"Als andere:r User:in ausführen","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, - {"i18nKey":"scripting.script.executeAsUser.info","bundleName":"I18nResources","translation":"The script is executed with all rights of the given user. Be careful! The execute-as functionality must be enabled inside the script as well to avoid mis-configurations.","translationDE":"Das Script wird mit ALLEN Rechten dieser oder der Benutzer:in ausgeführt. Bitte vorsichtig verwenden! Im Script selber muss diese Funktion auch aktiviert werden, um Fehlkonfigurationen zu vermeiden.","usedInClasses":["org.projectforge.business.scripting.ScriptDO"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.executableByUsers.info","bundleName":"I18nResources","translation":"These users are allowed to execute this script (but they can't see or modify the sources of this script).","translationDE":"Diese dürfen dieses Script ausführen (nicht einsehen oder ändern).","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.execute","bundleName":"I18nResources","translation":"Execute script","translationDE":"Script ausführen","usedInClasses":["org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.executeAsUser","bundleName":"I18nResources","translation":"Execute as user","translationDE":"Als andere:r User:in ausführen","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, + {"i18nKey":"scripting.script.executeAsUser.info","bundleName":"I18nResources","translation":"The script is executed with all rights of the given user. Be careful! The execute-as functionality must be enabled inside the script as well to avoid mis-configurations.","translationDE":"Das Script wird mit ALLEN Rechten dieser oder der Benutzer:in ausgeführt. Bitte vorsichtig verwenden! Im Script selber muss diese Funktion auch aktiviert werden, um Fehlkonfigurationen zu vermeiden.","usedInClasses":["org.projectforge.business.scripting.ScriptDO"],"usedInFiles":[]}, {"i18nKey":"scripting.script.includes","bundleName":"I18nResources","translation":"Embedded scripts","translationDE":"Eingebundene Scripts","usedInClasses":["org.projectforge.business.scripting.ScriptDO"],"usedInFiles":[]}, {"i18nKey":"scripting.script.name","bundleName":"I18nResources","translation":"Name","translationDE":"Name","usedInClasses":["org.projectforge.business.scripting.ScriptDO","org.projectforge.rest.scripting.AbstractScriptExecutePageRest"],"usedInFiles":[]}, {"i18nKey":"scripting.script.parameter","bundleName":"I18nResources","translation":"Parameter","translationDE":"Parameter","usedInClasses":["org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.scripting.MyScriptPagesRest","org.projectforge.rest.scripting.ScriptPagesRest"],"usedInFiles":[]}, @@ -2096,16 +2150,16 @@ {"i18nKey":"search.lastHours","bundleName":"I18nResources","translation":"Last {0} hours","translationDE":"Letzte {0} Stunden","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, {"i18nKey":"search.lastMinute","bundleName":"I18nResources","translation":"Last minute","translationDE":"Letzte Minute","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, {"i18nKey":"search.lastMinutes","bundleName":"I18nResources","translation":"Last {0} minutes","translationDE":"Letzte {0} Minuten","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, - {"i18nKey":"search.lucene.expression","bundleName":"I18nResources","translation":"Modified expression for search machine:","translationDE":"Modifizierter Ausdruck für Suchmaschine:","usedInClasses":["org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, - {"i18nKey":"search.maxRowsExceeded","bundleName":"I18nResources","translation":"Maximum number {0} of result size exceeded. Result list is truncated.","translationDE":"Die Maximalgröße {0} der Ergebnisliste ist überschritten und das Ergebnis enthält nicht alle gefundenen Elemente.","usedInClasses":["org.projectforge.rest.core.ResultSet","org.projectforge.web.wicket.AbstractListPage"],"usedInFiles":[]}, - {"i18nKey":"search.nextDays","bundleName":"I18nResources","translation":"Next {0} days","translationDE":"Nächste {0} Tage","usedInClasses":["org.projectforge.plugins.liquidityplanning.LiquidityEntryListForm"],"usedInFiles":[]}, + {"i18nKey":"search.lucene.expression","bundleName":"I18nResources","translation":"Modified expression for search machine:","translationDE":"Modifizierter Ausdruck für Suchmaschine:","usedInClasses":["org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, + {"i18nKey":"search.maxRowsExceeded","bundleName":"I18nResources","translation":"Maximum number {0} of result size exceeded. Result list is truncated.","translationDE":"Die Maximalgröße {0} der Ergebnisliste ist überschritten und das Ergebnis enthält nicht alle gefundenen Elemente.","usedInClasses":["org.projectforge.rest.core.ResultSet","org.projectforge.web.wicket.AbstractListPage"],"usedInFiles":[]}, + {"i18nKey":"search.nextDays","bundleName":"I18nResources","translation":"Next {0} days","translationDE":"Nächste {0} Tage","usedInClasses":["org.projectforge.plugins.liquidityplanning.LiquidityEntryListForm"],"usedInFiles":[]}, {"i18nKey":"search.parseError","bundleName":"I18nResources","translation":"Error while parsing search string: ''{0}''","translationDE":"Fehler beim Vearbeiten des Suchtexts: ''{0}''","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"search.periodOfModification","bundleName":"I18nResources","translation":"Period of modification","translationDE":"Änderungszeitraum","usedInClasses":["org.projectforge.web.core.SearchForm","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, + {"i18nKey":"search.periodOfModification","bundleName":"I18nResources","translation":"Period of modification","translationDE":"Änderungszeitraum","usedInClasses":["org.projectforge.web.core.SearchForm","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, {"i18nKey":"search.search","bundleName":"I18nResources","translation":"Search","translationDE":"Suche","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, {"i18nKey":"search.searchHistory","bundleName":"I18nResources","translation":"History","translationDE":"Historie","usedInClasses":["org.projectforge.web.core.SearchForm","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, - {"i18nKey":"search.searchHistory.additional.tooltip","bundleName":"I18nResources","translation":"If enabled all history entries will be searched for the given search string too.","translationDE":"Wenn gewählt, werden auch alle Änderungshistorieneinträge mit dem Suchausdruck durchsucht.","usedInClasses":["org.projectforge.web.core.SearchForm","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, + {"i18nKey":"search.searchHistory.additional.tooltip","bundleName":"I18nResources","translation":"If enabled all history entries will be searched for the given search string too.","translationDE":"Wenn gewählt, werden auch alle Änderungshistorieneinträge mit dem Suchausdruck durchsucht.","usedInClasses":["org.projectforge.web.core.SearchForm","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, {"i18nKey":"search.sinceYesterday","bundleName":"I18nResources","translation":"Since yesterday","translationDE":"Seit gestern","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, - {"i18nKey":"search.string.info","bundleName":"I18nResources","translation":"Use ''*'' for wild cards (automatically appended if token contraints only alpha numerical characters, white spaces or \"@._-\"), ''-string'' for negation, ''fieldname:string'' for searching in fields, for further information see help pages (lucene is used as search engine).\nSearch in fields: {0}.","translationDE":"''*'' für Teilausdrücke (automatisch angehängt, wenn nur alphanumerische Ausdrücke angegeben inkl. Leerzeichen und \"@._-\"), ''-ausdruck'' für Ausschlüsse, ''Feldname:Ausdruck'' für Teilwortsuche, s. auch Dokumentation (es wird Lucene als Suchmaschine eingesetzt).\nSuche in den Feldern: {0}.","usedInClasses":["org.projectforge.web.wicket.AbstractListPage"],"usedInFiles":[]}, + {"i18nKey":"search.string.info","bundleName":"I18nResources","translation":"Use ''*'' for wild cards (automatically appended if token contraints only alpha numerical characters, white spaces or \"@._-\"), ''-string'' for negation, ''fieldname:string'' for searching in fields, for further information see help pages (lucene is used as search engine).\nSearch in fields: {0}.","translationDE":"''*'' für Teilausdrücke (automatisch angehängt, wenn nur alphanumerische Ausdrücke angegeben inkl. Leerzeichen und \"@._-\"), ''-ausdruck'' für Ausschlüsse, ''Feldname:Ausdruck'' für Teilwortsuche, s. auch Dokumentation (es wird Lucene als Suchmaschine eingesetzt).\nSuche in den Feldern: {0}.","usedInClasses":["org.projectforge.web.wicket.AbstractListPage"],"usedInFiles":[]}, {"i18nKey":"search.string.info.title","bundleName":"I18nResources","translation":"Full text search","translationDE":"Volltextsuche","usedInClasses":["org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, {"i18nKey":"search.title","bundleName":"I18nResources","translation":"Search","translationDE":"Suche","usedInClasses":["org.projectforge.web.core.SearchPage"],"usedInFiles":[]}, {"i18nKey":"search.toDetailedSearch","bundleName":"I18nResources","translation":"To detailed search","translationDE":"Zur Detailsuche","usedInClasses":[],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/core/SearchAreaPanel.html"]}, @@ -2147,11 +2201,11 @@ {"i18nKey":"space.title.list","bundleName":"I18nResources","translation":"Spaces","translationDE":"Spaces","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"sql","bundleName":"I18nResources","translation":"SQL","translationDE":"SQL","usedInClasses":["org.projectforge.common.MimeType","org.projectforge.web.admin.GroovyConsoleForm","org.projectforge.web.admin.LuceneConsoleForm","org.projectforge.web.admin.SqlConsoleForm"],"usedInFiles":[]}, {"i18nKey":"statistics","bundleName":"I18nResources","translation":"Statistics","translationDE":"Statistik","usedInClasses":["org.projectforge.plugins.liquidityplanning.LiquidityEntryListForm","org.projectforge.web.core.importstorage.AbstractImportStoragePanel","org.projectforge.web.fibu.AbstractRechnungListForm","org.projectforge.web.fibu.AuftragListForm","org.projectforge.web.fibu.MonthlyEmployeeReportPage"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/core/importstorage/AbstractImportStoragePanel.html"]}, - {"i18nKey":"status","bundleName":"I18nResources","translation":"Status","translationDE":"Status","usedInClasses":["org.projectforge.business.book.BookDO","org.projectforge.business.fibu.AuftragDO","org.projectforge.business.fibu.AuftragsPositionDO","org.projectforge.business.fibu.EmployeeDO","org.projectforge.business.fibu.EmployeeDao","org.projectforge.business.fibu.KontoDO","org.projectforge.business.fibu.KundeDO","org.projectforge.business.fibu.OrderExport","org.projectforge.business.fibu.ProjektDO","org.projectforge.business.fibu.ProjektDao","org.projectforge.business.fibu.kost.Kost1DO","org.projectforge.business.fibu.kost.Kost2DO","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.humanresources.HRPlanningEntryDO","org.projectforge.business.orga.ContractDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.task.TaskDO","org.projectforge.business.task.TaskDao","org.projectforge.business.teamcal.servlet.TeamCalResponseServlet","org.projectforge.business.vacation.repository.VacationDao","org.projectforge.framework.jobs.AbstractJob","org.projectforge.framework.persistence.attr.impl.InternalAttrSchemaConstants","org.projectforge.plugins.todo.ToDoDao","org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.plugins.todo.rest.ToDoPagesRest","org.projectforge.rest.BookPagesRest","org.projectforge.rest.GroupPagesRest","org.projectforge.rest.UserPagesRest","org.projectforge.rest.VacationPagesRest","org.projectforge.rest.fibu.CustomerPagesRest","org.projectforge.rest.fibu.EmployeePagesRest","org.projectforge.rest.fibu.KontoPagesRest","org.projectforge.rest.fibu.ProjectPagesRest","org.projectforge.rest.fibu.RechnungMultiSelectedPageRest","org.projectforge.rest.fibu.RechnungPagesRest","org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.rest.orga.ContractPagesRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.web.fibu.AuftragEditForm","org.projectforge.web.fibu.AuftragListPage","org.projectforge.web.fibu.CustomerEditForm","org.projectforge.web.fibu.CustomerListPage","org.projectforge.web.fibu.KontoEditForm","org.projectforge.web.fibu.KontoListPage","org.projectforge.web.fibu.Kost1EditForm","org.projectforge.web.fibu.Kost1ListPage","org.projectforge.web.fibu.Kost2EditForm","org.projectforge.web.fibu.Kost2ListPage","org.projectforge.web.fibu.ProjektEditForm","org.projectforge.web.fibu.ProjektListPage","org.projectforge.web.fibu.RechnungEditForm","org.projectforge.web.fibu.RechnungListPage","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder","org.projectforge.web.teamcal.event.TeamAttendeesPanel"],"usedInFiles":["./projectforge-business/src/main/resources/mail/orderChangeNotification.html","./projectforge-wicket/src/main/java/org/projectforge/web/teamcal/event/TeamAttendeesPanel.html"]}, + {"i18nKey":"status","bundleName":"I18nResources","translation":"Status","translationDE":"Status","usedInClasses":["org.projectforge.business.book.BookDO","org.projectforge.business.fibu.AuftragDO","org.projectforge.business.fibu.AuftragsPositionDO","org.projectforge.business.fibu.EmployeeDO","org.projectforge.business.fibu.EmployeeDao","org.projectforge.business.fibu.KontoDO","org.projectforge.business.fibu.KundeDO","org.projectforge.business.fibu.OrderExport","org.projectforge.business.fibu.ProjektDO","org.projectforge.business.fibu.ProjektDao","org.projectforge.business.fibu.kost.Kost1DO","org.projectforge.business.fibu.kost.Kost2DO","org.projectforge.business.fibu.kost.KostZuweisungExport","org.projectforge.business.humanresources.HRPlanningEntryDO","org.projectforge.business.orga.ContractDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.task.TaskDO","org.projectforge.business.task.TaskDao","org.projectforge.business.teamcal.servlet.TeamCalResponseServlet","org.projectforge.business.vacation.repository.VacationDao","org.projectforge.framework.jobs.AbstractJob","org.projectforge.framework.persistence.attr.impl.InternalAttrSchemaConstants","org.projectforge.plugins.todo.ToDoDao","org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.plugins.todo.rest.ToDoPagesRest","org.projectforge.rest.BookPagesRest","org.projectforge.rest.GroupPagesRest","org.projectforge.rest.UserPagesRest","org.projectforge.rest.VacationPagesRest","org.projectforge.rest.fibu.CustomerPagesRest","org.projectforge.rest.fibu.EmployeePagesRest","org.projectforge.rest.fibu.KontoPagesRest","org.projectforge.rest.fibu.ProjectPagesRest","org.projectforge.rest.fibu.RechnungMultiSelectedPageRest","org.projectforge.rest.fibu.RechnungPagesRest","org.projectforge.rest.importer.AbstractImportPageRest","org.projectforge.rest.orga.ContractPagesRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.web.fibu.AuftragEditForm","org.projectforge.web.fibu.AuftragListPage","org.projectforge.web.fibu.CustomerEditForm","org.projectforge.web.fibu.CustomerListPage","org.projectforge.web.fibu.KontoEditForm","org.projectforge.web.fibu.KontoListPage","org.projectforge.web.fibu.Kost1EditForm","org.projectforge.web.fibu.Kost1ListPage","org.projectforge.web.fibu.Kost2EditForm","org.projectforge.web.fibu.Kost2ListPage","org.projectforge.web.fibu.ProjektEditForm","org.projectforge.web.fibu.ProjektListPage","org.projectforge.web.fibu.RechnungEditForm","org.projectforge.web.fibu.RechnungListPage","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder","org.projectforge.web.teamcal.event.TeamAttendeesPanel"],"usedInFiles":["./projectforge-business/src/main/resources/mail/orderChangeNotification.html","./projectforge-wicket/src/main/java/org/projectforge/web/teamcal/event/TeamAttendeesPanel.html"]}, {"i18nKey":"stop","bundleName":"I18nResources","translation":"Stop","translationDE":"Beenden","usedInClasses":["org.projectforge.rest.multiselect.AbstractMultiSelectedPage"],"usedInFiles":[]}, {"i18nKey":"sum","bundleName":"I18nResources","translation":"Sum","translationDE":"Summe","usedInClasses":["org.projectforge.business.fibu.datev.EmployeeSalaryExportDao","org.projectforge.web.fibu.MonthlyEmployeeReportPage","org.projectforge.web.humanresources.HRListPage"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/fibu/MonthlyEmployeeReportPage.html"]}, {"i18nKey":"system.admin.adminLogViewer.title","bundleName":"I18nResources","translation":"Admin log viewer","translationDE":"Adminprotokoll einsehen","usedInClasses":["org.projectforge.rest.admin.LogViewerPageRest"],"usedInFiles":[]}, - {"i18nKey":"system.admin.alertMessage.copyAndPaste.text","bundleName":"I18nResources","translation":"Attention: ProjectForge will not be available at 1 pm for approx. 5 minutes due to maintenance reasons. The new version {0} will be released.","translationDE":"Achtung: ProjectForge ist um 13:00 Uhr für ca. 5 Minuten aufgrund von Wartungsarbeiten nicht erreichbar! Es wird das neue Release {0} eingespielt.","usedInClasses":["org.projectforge.web.admin.AdminForm"],"usedInFiles":[]}, + {"i18nKey":"system.admin.alertMessage.copyAndPaste.text","bundleName":"I18nResources","translation":"Attention: ProjectForge will not be available at 1 pm for approx. 5 minutes due to maintenance reasons. The new version {0} will be released.","translationDE":"Achtung: ProjectForge ist um 13:00 Uhr für ca. 5 Minuten aufgrund von Wartungsarbeiten nicht erreichbar! Es wird das neue Release {0} eingespielt.","usedInClasses":["org.projectforge.web.admin.AdminForm"],"usedInFiles":[]}, {"i18nKey":"system.admin.alertMessage.copyAndPaste.title","bundleName":"I18nResources","translation":"For copy & paste","translationDE":"For copy & paste","usedInClasses":["org.projectforge.web.admin.AdminForm"],"usedInFiles":[]}, {"i18nKey":"system.admin.button.checkI18nProperties","bundleName":"I18nResources","translation":"Check i18n properties","translationDE":"Check i18n properties","usedInClasses":["org.projectforge.web.admin.AdminPage"],"usedInFiles":[]}, {"i18nKey":"system.admin.button.checkI18nProperties.tooltip","bundleName":"I18nResources","translation":"Check i18n properties for detecting missing translations in different languages.","translationDE":"Check i18n properties for detecting missing translations in different languages.","usedInClasses":["org.projectforge.web.admin.AdminPage"],"usedInFiles":[]}, @@ -2213,28 +2267,28 @@ {"i18nKey":"system.pluginAdmin.title","bundleName":"I18nResources","translation":"Plugins","translationDE":"Plugins","usedInClasses":["org.projectforge.web.admin.PluginListPage"],"usedInFiles":[]}, {"i18nKey":"system.statistics.databasePool","bundleName":"I18nResources","translation":"Data base pool","translationDE":"Data base pool","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, {"i18nKey":"system.statistics.title","bundleName":"I18nResources","translation":"System statistics","translationDE":"Systemstatistiken","usedInClasses":["org.projectforge.rest.SystemStatisticPageRest"],"usedInFiles":[]}, - {"i18nKey":"system.statistics.totalNumberOfHistoryEntries","bundleName":"I18nResources","translation":"Total number of history entries","translationDE":"Gesamtzahl aller Historierungseinträge","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, + {"i18nKey":"system.statistics.totalNumberOfHistoryEntries","bundleName":"I18nResources","translation":"Total number of history entries","translationDE":"Gesamtzahl aller Historierungseinträge","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, {"i18nKey":"system.statistics.totalNumberOfTasks","bundleName":"I18nResources","translation":"Total number of structure elements","translationDE":"Gesamtzahl aller Strukturelemente","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, {"i18nKey":"system.statistics.totalNumberOfTimesheets","bundleName":"I18nResources","translation":"Total number of time sheets","translationDE":"Gesamtzahl der Zeitberichte","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, {"i18nKey":"system.statistics.totalNumberOfUsers","bundleName":"I18nResources","translation":"Total number of users","translationDE":"Gesamtzahl der Benutzer:innen","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, - {"i18nKey":"system.statistics.totalTimesheetDurations","bundleName":"I18nResources","translation":"Total duration over all time sheets [days]","translationDE":"Gesamtdauer über alle Zeitberichte [Tage]","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, + {"i18nKey":"system.statistics.totalTimesheetDurations","bundleName":"I18nResources","translation":"Total duration over all time sheets [days]","translationDE":"Gesamtdauer über alle Zeitberichte [Tage]","usedInClasses":["org.projectforge.business.admin.DatabaseStatisticsBuilder"],"usedInFiles":[]}, {"i18nKey":"table.showing","bundleName":"I18nResources","translation":"Showing","translationDE":"Anzeige","usedInClasses":["org.projectforge.rest.core.AbstractPagesRest"],"usedInFiles":[]}, {"i18nKey":"task","bundleName":"I18nResources","translation":"Structure element","translationDE":"Strukturelement","usedInClasses":["org.projectforge.business.fibu.OrderExport","org.projectforge.business.fibu.ProjektDO","org.projectforge.business.gantt.GanttChartDO","org.projectforge.business.scripting.ScriptParameterType","org.projectforge.business.task.LegacyTaskFavorite","org.projectforge.business.task.TaskFavoritesService","org.projectforge.business.task.TaskNode","org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.business.user.UserPrefDOXmlDumpHook","org.projectforge.framework.access.AccessDao","org.projectforge.framework.access.AccessException","org.projectforge.framework.access.GroupTaskAccessDO","org.projectforge.framework.persistence.DaoConst","org.projectforge.framework.persistence.database.DatabaseInitTestDataService","org.projectforge.framework.persistence.user.entities.UserPrefXmlBeforePersistListener","org.projectforge.model.rest.RestPaths","org.projectforge.plugins.todo.ToDoDO","org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.plugins.todo.ToDoListForm","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.plugins.todo.ToDoType","org.projectforge.plugins.todo.rest.ToDoPagesRest","org.projectforge.registry.Registry","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.GroupAccessPagesRest","org.projectforge.rest.TimesheetFavoritesRest","org.projectforge.rest.TimesheetMultiSelectedPageRest","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.calendar.TimesheetEventsProvider","org.projectforge.rest.config.JacksonConfiguration","org.projectforge.rest.fibu.ProjectPagesRest","org.projectforge.rest.scripting.AbstractScriptExecutePageRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.ui.LayoutUtils","org.projectforge.web.access.AccessEditForm","org.projectforge.web.access.AccessListForm","org.projectforge.web.access.AccessListPage","org.projectforge.web.admin.TaskWizardForm","org.projectforge.web.calendar.TimesheetEventsProvider","org.projectforge.web.fibu.AuftragEditForm","org.projectforge.web.fibu.MonthlyEmployeeReportPage","org.projectforge.web.fibu.ProjektEditForm","org.projectforge.web.fibu.ProjektListPage","org.projectforge.web.gantt.GanttChartEditForm","org.projectforge.web.gantt.GanttChartEditPage","org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.gantt.GanttChartListPage","org.projectforge.web.task.TaskEditPage","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetEditSelectRecentDialogPanel","org.projectforge.web.timesheet.TimesheetListForm","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":["./projectforge-business/src/main/resources/mail/todoChangeNotification.html"]}, {"i18nKey":"task.assignedUser","bundleName":"I18nResources","translation":"Responsible user","translationDE":"Verantwortliche:r","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder"],"usedInFiles":[]}, {"i18nKey":"task.consumption","bundleName":"I18nResources","translation":"Consumption","translationDE":"Verbrauch","usedInClasses":["org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, - {"i18nKey":"task.deleted","bundleName":"I18nResources","translation":"deleted","translationDE":"gelöscht","usedInClasses":["org.projectforge.business.task.formatter.WicketTaskFormatter"],"usedInFiles":[]}, - {"i18nKey":"task.edit.maxHoursIngoredDueToAssignedOrders","bundleName":"I18nResources","translation":"This value will may-be be ignored - There are order positions with given person days assigned to this node or any subnode. A zero value suppress displaying a maximum value in the consumption bar.","translationDE":"Diese Angabe wird ggf. ignoriert. - Zu diesem Strukturelement oder einem Strukturunterelement wurden Aufträge zugeordnet. Die Angabe einer Null verhindert jedoch die Anzeige des Maximalwerts in den Verbrauchsbalken.","usedInClasses":["org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, - {"i18nKey":"task.error.couldNotDeleteRootTask","bundleName":"I18nResources","translation":"Root structure element can't be deleted!","translationDE":"Das Wurzelstrukturelement kann nicht gelöscht werden!","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, - {"i18nKey":"task.error.cyclicReference","bundleName":"I18nResources","translation":"Cyclic structure element path detected because parent structure element is the element itself or a descendant element.","translationDE":"Zyklische Strukturhierarchie entdeckt, weil ein Strukturelement sich selbst oder ein Strukturunterelement als übergeordnetes Strukturelement besitzt.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, - {"i18nKey":"task.error.duplicateChildTasks","bundleName":"I18nResources","translation":"Duplicate structure element titles for sister elements detected.","translationDE":"Strukturelemente müssen als Unterelemente unterschiedliche Titel haben.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, + {"i18nKey":"task.deleted","bundleName":"I18nResources","translation":"deleted","translationDE":"gelöscht","usedInClasses":["org.projectforge.business.task.formatter.WicketTaskFormatter"],"usedInFiles":[]}, + {"i18nKey":"task.edit.maxHoursIngoredDueToAssignedOrders","bundleName":"I18nResources","translation":"This value will may-be be ignored - There are order positions with given person days assigned to this node or any subnode. A zero value suppress displaying a maximum value in the consumption bar.","translationDE":"Diese Angabe wird ggf. ignoriert. - Zu diesem Strukturelement oder einem Strukturunterelement wurden Aufträge zugeordnet. Die Angabe einer Null verhindert jedoch die Anzeige des Maximalwerts in den Verbrauchsbalken.","usedInClasses":["org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, + {"i18nKey":"task.error.couldNotDeleteRootTask","bundleName":"I18nResources","translation":"Root structure element can't be deleted!","translationDE":"Das Wurzelstrukturelement kann nicht gelöscht werden!","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, + {"i18nKey":"task.error.cyclicReference","bundleName":"I18nResources","translation":"Cyclic structure element path detected because parent structure element is the element itself or a descendant element.","translationDE":"Zyklische Strukturhierarchie entdeckt, weil ein Strukturelement sich selbst oder ein Strukturunterelement als übergeordnetes Strukturelement besitzt.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, + {"i18nKey":"task.error.duplicateChildTasks","bundleName":"I18nResources","translation":"Duplicate structure element titles for sister elements detected.","translationDE":"Strukturelemente müssen als Unterelemente unterschiedliche Titel haben.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, {"i18nKey":"task.error.kost2Readonly","bundleName":"I18nResources","translation":"Kost2 is read-only for non accounting staff members.","translationDE":"Eine Kost2-Zuordnung kann nur durch die Buchhaltung vorgenommen werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, - {"i18nKey":"task.error.parentTaskNotFound","bundleName":"I18nResources","translation":"Parent structure element is required but not found.","translationDE":"Übergeordnetes Strukturelement wird benötigt, konnte aber nicht gefunden werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, - {"i18nKey":"task.error.parentTaskNotGiven","bundleName":"I18nResources","translation":"Parent structure element is required but not given.","translationDE":"Übergeordnetes Strukturelement muss angegeben sein.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, + {"i18nKey":"task.error.parentTaskNotFound","bundleName":"I18nResources","translation":"Parent structure element is required but not found.","translationDE":"Übergeordnetes Strukturelement wird benötigt, konnte aber nicht gefunden werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, + {"i18nKey":"task.error.parentTaskNotGiven","bundleName":"I18nResources","translation":"Parent structure element is required but not given.","translationDE":"Übergeordnetes Strukturelement muss angegeben sein.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, {"i18nKey":"task.error.protectTimesheetsUntilReadonly","bundleName":"I18nResources","translation":"The time sheet protection is read-only for non accounting staff members.","translationDE":"Der Zeitberichtsschutz kann nur durch die Buchhaltung manipuliert werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, - {"i18nKey":"task.error.protectionOfPrivacyReadonly","bundleName":"I18nResources","translation":"The flag privacy of protection is read-only for non accounting staff members.","translationDE":"Die Datenschutzoption kann nur durch die Buchhaltung geändert werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, - {"i18nKey":"task.error.timesheetBookingStatus2Readonly","bundleName":"I18nResources","translation":"The status of time sheet booking is read-only for non accouning staff members and non project managers.","translationDE":"Der Status für Zeitberichtsbuchungen kann nur durch die Buchhaltung oder Projektmanager manipuliert werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, + {"i18nKey":"task.error.protectionOfPrivacyReadonly","bundleName":"I18nResources","translation":"The flag privacy of protection is read-only for non accounting staff members.","translationDE":"Die Datenschutzoption kann nur durch die Buchhaltung geändert werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, + {"i18nKey":"task.error.timesheetBookingStatus2Readonly","bundleName":"I18nResources","translation":"The status of time sheet booking is read-only for non accouning staff members and non project managers.","translationDE":"Der Status für Zeitberichtsbuchungen kann nur durch die Buchhaltung oder Projektmanager manipuliert werden.","usedInClasses":["org.projectforge.business.task.TaskDao"],"usedInFiles":[]}, {"i18nKey":"task.favorite.new","bundleName":"I18nResources","translation":"New favorite of structure element","translationDE":"Neuer Strukturelementfavorit","usedInClasses":["org.projectforge.ui.LayoutUtils"],"usedInFiles":[]}, - {"i18nKey":"task.favorite.new.tooltip","bundleName":"I18nResources","translation":"You may save the chosen structure element as favorite here.","translationDE":"Das aktuell ausgewählte Strukturelement kann hier unter einem Namen als Favorit gespeichert werden.","usedInClasses":["org.projectforge.ui.LayoutUtils"],"usedInFiles":[]}, + {"i18nKey":"task.favorite.new.tooltip","bundleName":"I18nResources","translation":"You may save the chosen structure element as favorite here.","translationDE":"Das aktuell ausgewählte Strukturelement kann hier unter einem Namen als Favorit gespeichert werden.","usedInClasses":["org.projectforge.ui.LayoutUtils"],"usedInFiles":[]}, {"i18nKey":"task.favorites.tooltip","bundleName":"I18nResources","translation":"Organize here your structure elements as favorites.","translationDE":"Verwaltung von Strukturelementen als Favoriten","usedInClasses":["org.projectforge.ui.LayoutUtils"],"usedInFiles":[]}, {"i18nKey":"task.gantt.settings","bundleName":"I18nResources","translation":"Gantt settings","translationDE":"Ganttwerte","usedInClasses":["org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, {"i18nKey":"task.kost2list.blackList","bundleName":"I18nResources","translation":"Black list","translationDE":"Negativliste","usedInClasses":["org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, @@ -2246,19 +2300,19 @@ {"i18nKey":"task.menu.showAccessRights","bundleName":"I18nResources","translation":"Access rights","translationDE":"Zugriffsrechte","usedInClasses":["org.projectforge.web.task.TaskEditPage"],"usedInFiles":[]}, {"i18nKey":"task.menu.showTimesheets","bundleName":"I18nResources","translation":"Show time sheets","translationDE":"Zeitberichte anzeigen","usedInClasses":["org.projectforge.web.task.TaskEditPage"],"usedInFiles":[]}, {"i18nKey":"task.onlyBillable","bundleName":"I18nResources","translation":"only billable elements","translationDE":"nur fakturierbare Elemente","usedInClasses":["org.projectforge.web.timesheet.TimesheetListForm"],"usedInFiles":[]}, - {"i18nKey":"task.parentTask","bundleName":"I18nResources","translation":"Parent structure element","translationDE":"Übergeordnetes Strukturelement","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, + {"i18nKey":"task.parentTask","bundleName":"I18nResources","translation":"Parent structure element","translationDE":"Übergeordnetes Strukturelement","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, {"i18nKey":"task.path","bundleName":"I18nResources","translation":"Structure element path","translationDE":"Strukturhierarchie","usedInClasses":["org.projectforge.business.timesheet.TimesheetExport"],"usedInFiles":[]}, - {"i18nKey":"task.path.pleaseSelectTask","bundleName":"I18nResources","translation":"Please select structure element","translationDE":"Bitte Strukturelement wählen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"task.path.pleaseSelectTask","bundleName":"I18nResources","translation":"Please select structure element","translationDE":"Bitte Strukturelement wählen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"task.path.rootTask","bundleName":"I18nResources","translation":"Top level","translationDE":"Toplevel","usedInClasses":["org.projectforge.business.task.formatter.WicketTaskFormatter","org.projectforge.web.task.TaskSelectAutoCompleteFormComponent"],"usedInFiles":[]}, {"i18nKey":"task.progress","bundleName":"I18nResources","translation":"Progress","translationDE":"Fortschritt","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, {"i18nKey":"task.protectTimesheetsUntil","bundleName":"I18nResources","translation":"Protect time sheets until","translationDE":"Zeitberichtsschutz bis","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskTreeBuilder"],"usedInFiles":[]}, {"i18nKey":"task.protectTimesheetsUntil.short","bundleName":"I18nResources","translation":"Protect until","translationDE":"Schutz bis","usedInClasses":["org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder"],"usedInFiles":[]}, {"i18nKey":"task.protectionOfPrivacy","bundleName":"I18nResources","translation":"Protection of privacy","translationDE":"Datenschutz","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, - {"i18nKey":"task.protectionOfPrivacy.tooltip","bundleName":"I18nResources","translation":"If checked then users don't have access to the time sheets of other users assigned to this structure element or any sub element.","translationDE":"Wenn diese Option gewählt wird, dann kann nicht auf die Zeitberichte anderer Benutzer:innen unterhalb dieses Tasks zugegriffen werden.","usedInClasses":["org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, + {"i18nKey":"task.protectionOfPrivacy.tooltip","bundleName":"I18nResources","translation":"If checked then users don't have access to the time sheets of other users assigned to this structure element or any sub element.","translationDE":"Wenn diese Option gewählt wird, dann kann nicht auf die Zeitberichte anderer Benutzer:innen unterhalb dieses Tasks zugegriffen werden.","usedInClasses":["org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, {"i18nKey":"task.recursive","bundleName":"I18nResources","translation":"incl. all structure sub elements","translationDE":"inkl. aller Strukturunterelemente","usedInClasses":["org.projectforge.web.timesheet.TimesheetListForm"],"usedInFiles":[]}, {"i18nKey":"task.reference","bundleName":"I18nResources","translation":"Reference","translationDE":"Referenz","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskTreeBuilder"],"usedInFiles":[]}, {"i18nKey":"task.selectPanel.displayTask.tooltip","bundleName":"I18nResources","translation":"Display structure element.","translationDE":"Strukturelement anzeigen.","usedInClasses":["org.projectforge.web.task.TaskSelectPanel"],"usedInFiles":[]}, - {"i18nKey":"task.selectPanel.info","bundleName":"I18nResources","translation":"You may select folders by clicking in other columns of the row than the first.","translationDE":"Ordnerelement können ausgewählt werden, indem in eine andere Spalte geklickt wird (außer der ersten).","usedInClasses":["org.projectforge.rest.task.TaskServicesRest"],"usedInFiles":[]}, + {"i18nKey":"task.selectPanel.info","bundleName":"I18nResources","translation":"You may select folders by clicking in other columns of the row than the first.","translationDE":"Ordnerelement können ausgewählt werden, indem in eine andere Spalte geklickt wird (außer der ersten).","usedInClasses":["org.projectforge.rest.task.TaskServicesRest"],"usedInFiles":[]}, {"i18nKey":"task.selectPanel.noTasksFound","bundleName":"I18nResources","translation":"No structure elements found.","translationDE":"Keine Strukturelemente gefunden.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"task.selectPanel.selectAncestorTask.tooltip","bundleName":"I18nResources","translation":"Replace task by this ancestor structure element.","translationDE":"Strukturelement durch dieses Strukturoberelement ersetzen.","usedInClasses":["org.projectforge.web.task.TaskSelectPanel"],"usedInFiles":[]}, {"i18nKey":"task.status","bundleName":"I18nResources","translation":"Status of structure element","translationDE":"Status des Strukturelements","usedInClasses":[],"usedInFiles":[]}, @@ -2269,39 +2323,39 @@ {"i18nKey":"task.timesheetBooking","bundleName":"I18nResources","translation":"Time sheet booking","translationDE":"Zeitbuchungen","usedInClasses":["org.projectforge.business.task.TaskDO","org.projectforge.web.task.TaskEditForm"],"usedInFiles":[]}, {"i18nKey":"task.timesheetBooking.inherit","bundleName":"I18nResources","translation":"inherit","translationDE":"vererbt","usedInClasses":["org.projectforge.common.task.TimesheetBookingStatus"],"usedInFiles":[]}, {"i18nKey":"task.timesheetBooking.noBooking","bundleName":"I18nResources","translation":"no booking","translationDE":"keine Buchungen","usedInClasses":["org.projectforge.common.task.TimesheetBookingStatus"],"usedInFiles":[]}, - {"i18nKey":"task.timesheetBooking.onlyLeafs","bundleName":"I18nResources","translation":"only leaf nodes","translationDE":"nur Strukturelementblätter","usedInClasses":["org.projectforge.common.task.TimesheetBookingStatus"],"usedInFiles":[]}, - {"i18nKey":"task.timesheetBooking.opened","bundleName":"I18nResources","translation":"opened","translationDE":"geöffnet","usedInClasses":["org.projectforge.common.task.TimesheetBookingStatus"],"usedInFiles":[]}, + {"i18nKey":"task.timesheetBooking.onlyLeafs","bundleName":"I18nResources","translation":"only leaf nodes","translationDE":"nur Strukturelementblätter","usedInClasses":["org.projectforge.common.task.TimesheetBookingStatus"],"usedInFiles":[]}, + {"i18nKey":"task.timesheetBooking.opened","bundleName":"I18nResources","translation":"opened","translationDE":"geöffnet","usedInClasses":["org.projectforge.common.task.TimesheetBookingStatus"],"usedInFiles":[]}, {"i18nKey":"task.timesheetBooking.treeClosed","bundleName":"I18nResources","translation":"completely closed","translationDE":"komplett geschlossen","usedInClasses":["org.projectforge.common.task.TimesheetBookingStatus"],"usedInFiles":[]}, {"i18nKey":"task.title","bundleName":"I18nResources","translation":"Title","translationDE":"Titel","usedInClasses":["org.projectforge.business.gantt.GanttChartDao","org.projectforge.business.task.TaskDO","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.framework.access.AccessDao","org.projectforge.plugins.todo.ToDoDao","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.rest.GroupAccessPagesRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.web.access.AccessListPage","org.projectforge.web.fibu.ProjektListPage","org.projectforge.web.gantt.GanttChartListPage","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskTreeBuilder","org.projectforge.web.timesheet.TimesheetEditSelectRecentDialogPanel","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"task.title.add","bundleName":"I18nResources","translation":"Add new structure element","translationDE":"Neues Strukturelement","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"task.title.edit","bundleName":"I18nResources","translation":"Edit structure element","translationDE":"Strukturelement bearbeiten","usedInClasses":["org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.task.TaskEditPage","org.projectforge.web.task.TaskListPage"],"usedInFiles":[]}, {"i18nKey":"task.title.heading","bundleName":"I18nResources","translation":"Structure elements","translationDE":"Strukturelemente","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"task.title.list","bundleName":"I18nResources","translation":"Structure elements","translationDE":"Strukturelemente","usedInClasses":["org.projectforge.web.task.TaskEditPage","org.projectforge.web.task.TaskListPage"],"usedInFiles":[]}, - {"i18nKey":"task.title.list.select","bundleName":"I18nResources","translation":"Select structure element","translationDE":"Strukturelement auswählen","usedInClasses":["org.projectforge.ui.LayoutUtils","org.projectforge.web.task.TaskEditPage","org.projectforge.web.task.TaskListPage"],"usedInFiles":[]}, + {"i18nKey":"task.title.list.select","bundleName":"I18nResources","translation":"Select structure element","translationDE":"Strukturelement auswählen","usedInClasses":["org.projectforge.ui.LayoutUtils","org.projectforge.web.task.TaskEditPage","org.projectforge.web.task.TaskListPage"],"usedInFiles":[]}, {"i18nKey":"task.tree.close","bundleName":"I18nResources","translation":"Close structure element","translationDE":"Strukturelement zuklappen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"task.tree.explore","bundleName":"I18nResources","translation":"Close/open all structure sub elements","translationDE":"Alle Strukturelemente auf-/zuklappen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"task.tree.info","bundleName":"I18nResources","translation":"You may expand or collapse structure elements with structure sub elements by clicking the folder icons or the title of the element, you may select any element by clicking the row at any other position.","translationDE":"Strukturelemente können auf- und zugeklappt werden, indem auf die Ordnersymbole oder Titel des gewünschten Strukturelements geklickt wird. Zur Auswahl eines Strukturelements kann jede andere Stelle innerhalb der Zeile angeklickt werden.","usedInClasses":["org.projectforge.web.task.TaskTreePage"],"usedInFiles":[]}, + {"i18nKey":"task.tree.info","bundleName":"I18nResources","translation":"You may expand or collapse structure elements with structure sub elements by clicking the folder icons or the title of the element, you may select any element by clicking the row at any other position.","translationDE":"Strukturelemente können auf- und zugeklappt werden, indem auf die Ordnersymbole oder Titel des gewünschten Strukturelements geklickt wird. Zur Auswahl eines Strukturelements kann jede andere Stelle innerhalb der Zeile angeklickt werden.","usedInClasses":["org.projectforge.web.task.TaskTreePage"],"usedInFiles":[]}, {"i18nKey":"task.tree.open","bundleName":"I18nResources","translation":"Open structure element","translationDE":"Strukturelement aufklappen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"task.tree.perspective","bundleName":"I18nResources","translation":"structure tree","translationDE":"Baumansicht","usedInClasses":["org.projectforge.web.task.TaskListForm"],"usedInFiles":[]}, {"i18nKey":"task.tree.rootNode","bundleName":"I18nResources","translation":"Root node","translationDE":"Wurzelstrukturelement","usedInClasses":["org.projectforge.ui.LayoutUtils"],"usedInFiles":[]}, {"i18nKey":"task.tree.title","bundleName":"I18nResources","translation":"structure tree","translationDE":"Strukturbaum","usedInClasses":["org.projectforge.web.task.TaskTreePage"],"usedInFiles":[]}, - {"i18nKey":"task.tree.title.select","bundleName":"I18nResources","translation":"Select structure element","translationDE":"Strukturelement auswählen","usedInClasses":["org.projectforge.web.task.TaskTreePage"],"usedInFiles":[]}, + {"i18nKey":"task.tree.title.select","bundleName":"I18nResources","translation":"Select structure element","translationDE":"Strukturelement auswählen","usedInClasses":["org.projectforge.web.task.TaskTreePage"],"usedInFiles":[]}, {"i18nKey":"task.wizard.action","bundleName":"I18nResources","translation":"Action","translationDE":"Aktion","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, - {"i18nKey":"task.wizard.action.noactionRequired","bundleName":"I18nResources","translation":"Nothing will be further done because you haven't defined any group, therefore no access rights will be created.","translationDE":"Keine Aktion notwendig, da keine Gruppen ausgewählt wurden. Demnach müssen keine Zugriffsrechte angelegt werden.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, - {"i18nKey":"task.wizard.action.taskAndgroupsGiven","bundleName":"I18nResources","translation":"The required access rights of the group(s) defined above will be set if you click on the create button. You can change these access rights via the menu item access management whenever needed.","translationDE":"Die notwendigen Zugriffsrechte für die oben angegebene(n) Gruppe(n) werden angelegt, nachdem der Anlegen-Button gedrückt wird. Diese können Sie jederzeit unter dem Menüpunkt Zugriffsverwaltung einsehen und ändern.","usedInClasses":["org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, + {"i18nKey":"task.wizard.action.noactionRequired","bundleName":"I18nResources","translation":"Nothing will be further done because you haven't defined any group, therefore no access rights will be created.","translationDE":"Keine Aktion notwendig, da keine Gruppen ausgewählt wurden. Demnach müssen keine Zugriffsrechte angelegt werden.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, + {"i18nKey":"task.wizard.action.taskAndgroupsGiven","bundleName":"I18nResources","translation":"The required access rights of the group(s) defined above will be set if you click on the create button. You can change these access rights via the menu item access management whenever needed.","translationDE":"Die notwendigen Zugriffsrechte für die oben angegebene(n) Gruppe(n) werden angelegt, nachdem der Anlegen-Button gedrückt wird. Diese können Sie jederzeit unter dem Menüpunkt Zugriffsverwaltung einsehen und ändern.","usedInClasses":["org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, {"i18nKey":"task.wizard.button.createGroup","bundleName":"I18nResources","translation":"create group","translationDE":"Gruppe anlegen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"task.wizard.button.createGroup.tooltip","bundleName":"I18nResources","translation":"You can choose an existing group or create a new group by using this button.","translationDE":"Sie können eine existierende Benutzergruppe wählen oder eine neue durch Anklicken dieses Buttons anlegen.","usedInClasses":["org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, + {"i18nKey":"task.wizard.button.createGroup.tooltip","bundleName":"I18nResources","translation":"You can choose an existing group or create a new group by using this button.","translationDE":"Sie können eine existierende Benutzergruppe wählen oder eine neue durch Anklicken dieses Buttons anlegen.","usedInClasses":["org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, {"i18nKey":"task.wizard.button.createTask","bundleName":"I18nResources","translation":"create structure element","translationDE":"Strukturelement anlegen","usedInClasses":["org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, - {"i18nKey":"task.wizard.button.createTask.tooltip","bundleName":"I18nResources","translation":"You can choose an existing structure element or create a new element by using this button.","translationDE":"Sie können ein existierendes Strukturelement wählen oder ein neues durch Anklicken dieses Buttons anlegen.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"task.wizard.button.createTask.tooltip","bundleName":"I18nResources","translation":"You can choose an existing structure element or create a new element by using this button.","translationDE":"Sie können ein existierendes Strukturelement wählen oder ein neues durch Anklicken dieses Buttons anlegen.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"task.wizard.finish","bundleName":"I18nResources","translation":"Finish","translationDE":"Fertig stellen","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, - {"i18nKey":"task.wizard.intro","bundleName":"I18nResources","translation":"Use this wizard to add a new structure element which represents e. g. a project with assigned groups and users. The assigned users will have access rights to this structure element (e. g. for booking time sheet etc.).","translationDE":"Benutzen Sie diesen Assistenten, um ein neues Strukturelement anzulegen. Dieses Strukturelement kann ein Projekt o. ä. repräsentieren auf welche Nutzer und Gruppen Zugriff haben sollen (z. B. für Zeitberichtserfassungen).","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, + {"i18nKey":"task.wizard.intro","bundleName":"I18nResources","translation":"Use this wizard to add a new structure element which represents e. g. a project with assigned groups and users. The assigned users will have access rights to this structure element (e. g. for booking time sheet etc.).","translationDE":"Benutzen Sie diesen Assistenten, um ein neues Strukturelement anzulegen. Dieses Strukturelement kann ein Projekt o. ä. repräsentieren auf welche Nutzer und Gruppen Zugriff haben sollen (z. B. für Zeitberichtserfassungen).","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, {"i18nKey":"task.wizard.managerGroup","bundleName":"I18nResources","translation":"Managing users (optional)","translationDE":"Teammanager:in (optional)","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, {"i18nKey":"task.wizard.managerGroup.groupNameSuffix","bundleName":"I18nResources","translation":"managers","translationDE":"Projektmanagement","usedInClasses":["org.projectforge.web.admin.TaskWizardForm"],"usedInFiles":[]}, - {"i18nKey":"task.wizard.managerGroup.intro","bundleName":"I18nResources","translation":"The managing users have more rights. They're able to modifiy the time sheets of other team members. If they're also project managers they've the right to do HR planning etc.","translationDE":"Die Teammanager:innen haben mehr Rechte, so dürfen sie beispielsweise die Zeitberichte anderer Nutzer ändern. Wenn sie die Rolle Projektmanagement (Gruppe PF_MANAGER) haben, dürfen sie auch HR-Planungen vornehmen.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, + {"i18nKey":"task.wizard.managerGroup.intro","bundleName":"I18nResources","translation":"The managing users have more rights. They're able to modifiy the time sheets of other team members. If they're also project managers they've the right to do HR planning etc.","translationDE":"Die Teammanager:innen haben mehr Rechte, so dürfen sie beispielsweise die Zeitberichte anderer Nutzer ändern. Wenn sie die Rolle Projektmanagement (Gruppe PF_MANAGER) haben, dürfen sie auch HR-Planungen vornehmen.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, {"i18nKey":"task.wizard.pageTitle","bundleName":"I18nResources","translation":"Structure wizard","translationDE":"Strukturassistent","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardPage"],"usedInFiles":[]}, - {"i18nKey":"task.wizard.task.intro","bundleName":"I18nResources","translation":"For this structure element the rights for the given groups will be configured: For all ancestor elements a minimal read access will be configured for the groups, but all other elements in the upper hierarchy will not be accessible without further grants.","translationDE":"Für dieses Strukturelement sollen die Rechte automatisch für die unten angegebenen Gruppen eingerichtet werden. Dabei wird für alle Oberelemente ein minimales Leserecht, so dass aus der Baumansicht dieses Element für die Gruppen eingesehen werden kann. Andere Elemente aus höheren Ebenen bleiben unsichtbar.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, + {"i18nKey":"task.wizard.task.intro","bundleName":"I18nResources","translation":"For this structure element the rights for the given groups will be configured: For all ancestor elements a minimal read access will be configured for the groups, but all other elements in the upper hierarchy will not be accessible without further grants.","translationDE":"Für dieses Strukturelement sollen die Rechte automatisch für die unten angegebenen Gruppen eingerichtet werden. Dabei wird für alle Oberelemente ein minimales Leserecht, so dass aus der Baumansicht dieses Element für die Gruppen eingesehen werden kann. Andere Elemente aus höheren Ebenen bleiben unsichtbar.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, {"i18nKey":"task.wizard.team","bundleName":"I18nResources","translation":"Team users (optional)","translationDE":"Team (optional)","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, - {"i18nKey":"task.wizard.team.intro","bundleName":"I18nResources","translation":"The team members are able to create and modify structure sub elements and to book their time sheets.","translationDE":"Die Teammitglieder haben das Recht, Strukturunterelemente anzulegen oder zu ändern, sowie eigene Zeitberichte zu erfassen.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, + {"i18nKey":"task.wizard.team.intro","bundleName":"I18nResources","translation":"The team members are able to create and modify structure sub elements and to book their time sheets.","translationDE":"Die Teammitglieder haben das Recht, Strukturunterelemente anzulegen oder zu ändern, sowie eigene Zeitberichte zu erfassen.","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest"],"usedInFiles":[]}, {"i18nKey":"templates","bundleName":"I18nResources","translation":"Templates","translationDE":"Vorlagen","usedInClasses":["org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.plugins.todo.ToDoListPage","org.projectforge.web.teamcal.event.TeamEventListForm"],"usedInFiles":[]}, {"i18nKey":"templates.new","bundleName":"I18nResources","translation":"New template","translationDE":"Neue Vorlage","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"text","bundleName":"I18nResources","translation":"Text","translationDE":"Text","usedInClasses":["org.projectforge.business.fibu.datev.BuchungssatzExcelImporter","org.projectforge.business.fibu.datev.DatevImportDao","org.projectforge.business.orga.ContractDO","org.projectforge.common.MimeType","org.projectforge.export.SVGHelper","org.projectforge.rest.calendar.BarcodeServicesRest","org.projectforge.rest.orga.AccountingRecordPagesRest","org.projectforge.rest.orga.ContractPagesRest","org.projectforge.rest.pub.MessagingServiceRest","org.projectforge.rest.pub.PhoneLookupRest","org.projectforge.web.fibu.AbstractRechnungEditForm","org.projectforge.web.fibu.AccountingRecordEditForm","org.projectforge.web.fibu.AccountingRecordListPage","org.projectforge.web.wicket.components.AjaxMaxLengthEditableLabel","org.projectforge.web.wicket.components.MaxLengthTextField","org.projectforge.web.wicket.components.SingleTextFieldPanel","org.projectforge.web.wicket.flowlayout.DiffTextPanel","org.projectforge.web.wicket.flowlayout.DivTextPanel","org.projectforge.web.wicket.flowlayout.FieldsetPanel","org.projectforge.web.wicket.flowlayout.IconButtonPanel","org.projectforge.web.wicket.flowlayout.ParTextPanel","org.projectforge.web.wicket.flowlayout.TextLinkPanel","org.projectforge.web.wicket.flowlayout.TextPanel","org.projectforge.web.wicket.flowlayout.TextStyle","org.projectforge.web.wicket.flowlayout.ToggleContainerPanel"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/common/ColorPickerPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/core/NavTopPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/CustomerSelectPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/EmployeeSelectPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/KontoSelectPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/NewCustomerSelectPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/NewProjektSelectPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/gantt/GanttChartEditTreeTablePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/humanresources/HRPlanningEditTablePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/user/NewGroupSelectPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/user/UserSelectPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/DatePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/JodaDatePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/LocalDatePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/SingleTextFieldPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/TextFieldOrLabelPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/components/TimeZonePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/DiffTextPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/DivTextPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/IconButtonPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/InputPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/ParTextPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/Select2MultiChoicePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/TextLinkPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/TextPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/ToggleContainerPanel.html"]}, @@ -2344,43 +2398,43 @@ {"i18nKey":"timeleft.years.one","bundleName":"I18nResources","translation":"in a year","translationDE":"in einem Jahr","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"timesheet","bundleName":"I18nResources","translation":"Time-sheet","translationDE":"Zeitbericht","usedInClasses":["org.projectforge.Constants","org.projectforge.business.timesheet.TimesheetFavoritesService","org.projectforge.framework.persistence.DaoConst","org.projectforge.model.rest.RestPaths","org.projectforge.registry.Registry","org.projectforge.rest.calendar.CalendarServicesRest","org.projectforge.rest.calendar.FullCalendarEvent","org.projectforge.rest.calendar.TimesheetEventsProvider","org.projectforge.web.calendar.TimesheetEventsProvider","org.projectforge.web.timesheet.TimesheetEditPage","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"timesheet.break","bundleName":"I18nResources","translation":"Break","translationDE":"leer","usedInClasses":["org.projectforge.rest.calendar.TimesheetEventsProvider","org.projectforge.web.calendar.TimesheetEventsProvider"],"usedInFiles":[]}, - {"i18nKey":"timesheet.description","bundleName":"I18nResources","translation":"Activity report","translationDE":"Tätigkeitsbericht","usedInClasses":["org.projectforge.business.humanresources.HRPlanningExport","org.projectforge.business.timesheet.TimesheetDO","org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetEditSelectRecentDialogPanel"],"usedInFiles":[]}, + {"i18nKey":"timesheet.description","bundleName":"I18nResources","translation":"Activity report","translationDE":"Tätigkeitsbericht","usedInClasses":["org.projectforge.business.humanresources.HRPlanningExport","org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetEditSelectRecentDialogPanel"],"usedInFiles":[]}, {"i18nKey":"timesheet.duration","bundleName":"I18nResources","translation":"Duration","translationDE":"Dauer","usedInClasses":["org.projectforge.business.timesheet.TimesheetExport","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.calendar.CalendarForm","org.projectforge.web.teamcal.event.MyWicketEvent","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.copyNoMatchingKost2","bundleName":"I18nResources","translation":"No Kost2 available or matching for this timesheet copy. This probably means the structure elemnt of this timesheet has moved into another subtree. resolve problem manually by choosing kost2.","translationDE":"Keine Kost2 Id für diese Zeiberichtskopie verfügbar oder keine übereinstimmende mit dem Orginal gefunden. Wahrscheinlich wurde das Strukturelement des Zeitberichts in einen anderen Unterbaum verschoben. Zur Lösung des Problems bitte manuell Kost2 Id wählen.","usedInClasses":["org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.copyNoMatchingKost2","bundleName":"I18nResources","translation":"No Kost2 available or matching for this timesheet copy. This probably means the structure elemnt of this timesheet has moved into another subtree. resolve problem manually by choosing kost2.","translationDE":"Keine Kost2 Id für diese Zeiberichtskopie verfügbar oder keine übereinstimmende mit dem Orginal gefunden. Wahrscheinlich wurde das Strukturelement des Zeitberichts in einen anderen Unterbaum verschoben. Zur Lösung des Problems bitte manuell Kost2 Id wählen.","usedInClasses":["org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, {"i18nKey":"timesheet.error.filter.needMore","bundleName":"I18nResources","translation":"Please enter further filter settings such as date or structure element.","translationDE":"Zu wenige Filterangaben: Bitte Datum und/oder Strukturelement angeben.","usedInClasses":["org.projectforge.web.timesheet.TimesheetListForm"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.invalidKost2","bundleName":"I18nResources","translation":"No valid cost 2 id.","translationDE":"Keine gültige Kost2 Id.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.invalidKost2","bundleName":"I18nResources","translation":"No valid cost 2 id.","translationDE":"Keine gültige Kost2 Id.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, {"i18nKey":"timesheet.error.invalidTaskId","bundleName":"I18nResources","translation":"Structure element not found.","translationDE":"Das Strukturelement wurde leider nicht gefunden.","usedInClasses":["org.projectforge.web.task.TaskSelectAutoCompleteFormComponent"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.kost2NeededChooseSubTask","bundleName":"I18nResources","translation":"Kost2 required, please choose sub structure element with Kost2s.","translationDE":"Bitte Kost2 auswählen und ggf. Strukturunterelement mit Kost2s bebuchen.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.kost2Required","bundleName":"I18nResources","translation":"Please choose cost 2 id.","translationDE":"Bitte Kost2 auswählen.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.fibu.Kost2DropDownChoice","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.massupdate.couldnotconvertkost2","bundleName":"I18nResources","translation":"Mass update not possible for time sheet. The destination task has multiple kost2 entries and no corresponding kost2 art.","translationDE":"Massenänderung für Zeitbericht nicht möglich. Das Ziel-Strukturelement hat mehrere Kost2-Einträge aber es gibt keine passende Kost2-Art.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.massupdate.kost2notsupported","bundleName":"I18nResources","translation":"Mass update is not possible for time sheet. The destination task does not support the given kost2.","translationDE":"Massenänderung für Zeitbericht nicht möglich. Das Ziel-Strukturelement unterstützt nicht die gewählte Kost2.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.massupdate.kost2null","bundleName":"I18nResources","translation":"Mass update not possible for time sheet. The destination task requires a kost2.","translationDE":"Massenänderung für Zeitbericht nicht möglich. Für das Ziel-Strukturelement wird eine Kost2 benötigt.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.maximumDurationExceeded","bundleName":"I18nResources","translation":"Maximum of duration exceeded.","translationDE":"Maximal zugelassene Dauer überschritten.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.noAccess","bundleName":"I18nResources","translation":"Not possible, missing rights for this action.","translationDE":"Fehlende Berechtigung für die ausgewählte Aktion.","usedInClasses":["org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.overlapping","bundleName":"I18nResources","translation":"Not possible, timesheet is overlapping.","translationDE":"Die ausgewählte Aktion ist aufgrund einer zeitlichen Überschneidung nicht möglich.","usedInClasses":["org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.taskNotBookable.onlyLeafsAllowedForBooking","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because only leaf elements are bookable.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da nur Strukturblätterelemente (d. h. Strukturelemente ohne Unterelementen) bebucht werden können.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.kost2NeededChooseSubTask","bundleName":"I18nResources","translation":"Kost2 required, please choose sub structure element with Kost2s.","translationDE":"Bitte Kost2 auswählen und ggf. Strukturunterelement mit Kost2s bebuchen.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.kost2Required","bundleName":"I18nResources","translation":"Please choose cost 2 id.","translationDE":"Bitte Kost2 auswählen.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.fibu.Kost2DropDownChoice","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.massupdate.couldnotconvertkost2","bundleName":"I18nResources","translation":"Mass update not possible for time sheet. The destination task has multiple kost2 entries and no corresponding kost2 art.","translationDE":"Massenänderung für Zeitbericht nicht möglich. Das Ziel-Strukturelement hat mehrere Kost2-Einträge aber es gibt keine passende Kost2-Art.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.massupdate.kost2notsupported","bundleName":"I18nResources","translation":"Mass update is not possible for time sheet. The destination task does not support the given kost2.","translationDE":"Massenänderung für Zeitbericht nicht möglich. Das Ziel-Strukturelement unterstützt nicht die gewählte Kost2.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.massupdate.kost2null","bundleName":"I18nResources","translation":"Mass update not possible for time sheet. The destination task requires a kost2.","translationDE":"Massenänderung für Zeitbericht nicht möglich. Für das Ziel-Strukturelement wird eine Kost2 benötigt.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.maximumDurationExceeded","bundleName":"I18nResources","translation":"Maximum of duration exceeded.","translationDE":"Maximal zugelassene Dauer überschritten.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.noAccess","bundleName":"I18nResources","translation":"Not possible, missing rights for this action.","translationDE":"Fehlende Berechtigung für die ausgewählte Aktion.","usedInClasses":["org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.overlapping","bundleName":"I18nResources","translation":"Not possible, timesheet is overlapping.","translationDE":"Die ausgewählte Aktion ist aufgrund einer zeitlichen Überschneidung nicht möglich.","usedInClasses":["org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.taskNotBookable.onlyLeafsAllowedForBooking","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because only leaf elements are bookable.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da nur Strukturblätterelemente (d. h. Strukturelemente ohne Unterelementen) bebucht werden können.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, {"i18nKey":"timesheet.error.taskNotBookable.orderPositionsFoundInSubTasks","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because at least one order position is assigned to a sub element.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da Auftragszuordnungen in Unterelementen existieren.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.taskNotBookable.taskClosedForBooking","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because the element is closed for booking of time sheets.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da es für Zeitberichtsbuchungen geschlossen ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.taskNotBookable.taskDeleted","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because it''s deleted.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da es gelöscht ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.taskNotBookable.taskNotOpened","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because it''s not opened.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da es nicht geöffnet ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.taskNotBookable.treeClosedForBooking","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because the structure tree is closed for booking of time sheets.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da der komplette Strukturbaum für Zeitberichtsbuchungen geschlossen ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.taskNotBookable.taskClosedForBooking","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because the element is closed for booking of time sheets.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da es für Zeitberichtsbuchungen geschlossen ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.taskNotBookable.taskDeleted","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because it''s deleted.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da es gelöscht ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.taskNotBookable.taskNotOpened","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because it''s not opened.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da es nicht geöffnet ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.calendar.CalendarPanel"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.taskNotBookable.treeClosedForBooking","bundleName":"I18nResources","translation":"The structure element {0} is not bookable because the structure tree is closed for booking of time sheets.","translationDE":"Das Strukturelement {0} kann nicht bebucht werden, da der komplette Strukturbaum für Zeitberichtsbuchungen geschlossen ist.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, {"i18nKey":"timesheet.error.timeperiodOverlapDetection","bundleName":"I18nResources","translation":"The time sheet has a time period collision with time sheet #{0} from {1} to {2} for the same user.","translationDE":"Der Zeitbericht kollidiert mit dem Zeitbericht #{0} (gleiche:r Benutzer:in) von {1} bis {2}.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, - {"i18nKey":"timesheet.error.timesheetProtectionVioloation","bundleName":"I18nResources","translation":"The time sheet violates the time sheet protection of structure element ''{0}'' which is set until {1}. Please contact the accounting staff.","translationDE":"Der Zeitbericht verletzt den Zeitberichtsschutz des Strukturelements ''{0}'', welcher bis einschließlich {1} gesetzt ist. Bitte Rücksprache mit der Buchhaltung nehmen.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, + {"i18nKey":"timesheet.error.timesheetProtectionVioloation","bundleName":"I18nResources","translation":"The time sheet violates the time sheet protection of structure element ''{0}'' which is set until {1}. Please contact the accounting staff.","translationDE":"Der Zeitbericht verletzt den Zeitberichtsschutz des Strukturelements ''{0}'', welcher bis einschließlich {1} gesetzt ist. Bitte Rücksprache mit der Buchhaltung nehmen.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao"],"usedInFiles":[]}, {"i18nKey":"timesheet.error.zeroDuration","bundleName":"I18nResources","translation":"Time sheet has zero duration.","translationDE":"Der Zeitbericht hat keine Dauer.","usedInClasses":["org.projectforge.business.timesheet.TimesheetDao","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, {"i18nKey":"timesheet.filter.withTimeperiodCollision","bundleName":"I18nResources","translation":"Only collisions","translationDE":"Nur kollidierte","usedInClasses":["org.projectforge.web.timesheet.TimesheetListForm"],"usedInFiles":[]}, - {"i18nKey":"timesheet.filter.withTimeperiodCollision.tooltip","bundleName":"I18nResources","translation":"Show only time-sheets with collisions, meaning time-sheets with an overlap of the time-period with another time-sheet of the same user.","translationDE":"Es werden nur Zeitberichte angezeigt, die mit anderen Zeitberichten (gleiche:r Nutzer:in) kollidieren (sich überlappen).","usedInClasses":["org.projectforge.web.timesheet.TimesheetListForm"],"usedInFiles":[]}, - {"i18nKey":"timesheet.iCalSubscription","bundleName":"I18nResources","translation":"Subscribe time sheets in iCal format (*.ics) for the logged-in user.","translationDE":"Zeitberichte im iCal-Format für den/die angemeldete:n Benutzer:in exportieren (*.ics).","usedInClasses":["org.projectforge.web.humanresources.HRPlanningListPage","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, + {"i18nKey":"timesheet.filter.withTimeperiodCollision.tooltip","bundleName":"I18nResources","translation":"Show only time-sheets with collisions, meaning time-sheets with an overlap of the time-period with another time-sheet of the same user.","translationDE":"Es werden nur Zeitberichte angezeigt, die mit anderen Zeitberichten (gleiche:r Nutzer:in) kollidieren (sich überlappen).","usedInClasses":["org.projectforge.web.timesheet.TimesheetListForm"],"usedInFiles":[]}, + {"i18nKey":"timesheet.iCalSubscription","bundleName":"I18nResources","translation":"Subscribe time sheets in iCal format (*.ics) for the logged-in user.","translationDE":"Zeitberichte im iCal-Format für den/die angemeldete:n Benutzer:in exportieren (*.ics).","usedInClasses":["org.projectforge.web.humanresources.HRPlanningListPage","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"timesheet.icsExport","bundleName":"I18nResources","translation":"ics export","translationDE":"ics-Export","usedInClasses":["org.projectforge.web.humanresources.HRPlanningListPage","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, - {"i18nKey":"timesheet.location","bundleName":"I18nResources","translation":"Location","translationDE":"Ort","usedInClasses":["org.projectforge.business.timesheet.TimesheetDO","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.calendar.TimesheetEventsProvider","org.projectforge.web.calendar.TimesheetEventsProvider","org.projectforge.web.teamcal.event.TeamCalEventProvider","org.projectforge.web.timesheet.TimesheetEditSelectRecentDialogPanel","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, - {"i18nKey":"timesheet.location.tooltip","bundleName":"I18nResources","translation":"You may remove locations from the auto-completion list by simply clicking the remove icon (cross) at the end of the line of the location to delete. Any removed location can be used again by simply using it again.","translationDE":"Einträge aus der Vorschlagsliste können entfernt werden, indem einfach das Entfernen-Symbol (Kreuz) am Ende der Zeile des zu löschenden Orts geklickt wird. Entfernte Orte können wieder aufgenommen werden, indem sie einfach wieder erneut verwendet werden.","usedInClasses":["org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, - {"i18nKey":"timesheet.massupdate.kost.info","bundleName":"I18nResources","translation":"If you update the structure element of a project to another resulting in other available cost entries, cost2 entries will be migrated while preserving the type of cost if possible (last 2 digits).","translationDE":"Wenn Zeitberichte eines Projekts zu einem anderen transferiert werden, wird der Kostenträger automatisch migriert, falls möglich, d. h. die Kostenart (letzte beiden Ziffern) bleibt erhalten.","usedInClasses":["org.projectforge.rest.TimesheetMultiSelectedPageRest"],"usedInFiles":[]}, - {"i18nKey":"timesheet.massupdate.updateTask","bundleName":"I18nResources","translation":"Update structure element for all time sheets.","translationDE":"Strukturelement für alle Zeitberichte ändern","usedInClasses":["org.projectforge.rest.TimesheetMultiSelectedPageRest"],"usedInFiles":[]}, + {"i18nKey":"timesheet.location","bundleName":"I18nResources","translation":"Location","translationDE":"Ort","usedInClasses":["org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.calendar.TimesheetEventsProvider","org.projectforge.web.calendar.TimesheetEventsProvider","org.projectforge.web.teamcal.event.TeamCalEventProvider","org.projectforge.web.timesheet.TimesheetEditSelectRecentDialogPanel","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, + {"i18nKey":"timesheet.location.tooltip","bundleName":"I18nResources","translation":"You may remove locations from the auto-completion list by simply clicking the remove icon (cross) at the end of the line of the location to delete. Any removed location can be used again by simply using it again.","translationDE":"Einträge aus der Vorschlagsliste können entfernt werden, indem einfach das Entfernen-Symbol (Kreuz) am Ende der Zeile des zu löschenden Orts geklickt wird. Entfernte Orte können wieder aufgenommen werden, indem sie einfach wieder erneut verwendet werden.","usedInClasses":["org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, + {"i18nKey":"timesheet.massupdate.kost.info","bundleName":"I18nResources","translation":"If you update the structure element of a project to another resulting in other available cost entries, cost2 entries will be migrated while preserving the type of cost if possible (last 2 digits).","translationDE":"Wenn Zeitberichte eines Projekts zu einem anderen transferiert werden, wird der Kostenträger automatisch migriert, falls möglich, d. h. die Kostenart (letzte beiden Ziffern) bleibt erhalten.","usedInClasses":["org.projectforge.rest.TimesheetMultiSelectedPageRest"],"usedInFiles":[]}, + {"i18nKey":"timesheet.massupdate.updateTask","bundleName":"I18nResources","translation":"Update structure element for all time sheets.","translationDE":"Strukturelement für alle Zeitberichte ändern","usedInClasses":["org.projectforge.rest.TimesheetMultiSelectedPageRest"],"usedInFiles":[]}, {"i18nKey":"timesheet.multiselected.title","bundleName":"I18nResources","translation":"Multi selected time sheets","translationDE":"Mehrfachauswahl Zeitberichte","usedInClasses":["org.projectforge.rest.TimesheetMultiSelectedPageRest"],"usedInFiles":[]}, {"i18nKey":"timesheet.recent","bundleName":"I18nResources","translation":"Recent","translationDE":"Zuletzt verwendet","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, {"i18nKey":"timesheet.recent.select","bundleName":"I18nResources","translation":"Recent time sheets","translationDE":"Zuletzt bearbeitete Berichte zur Auswahl","usedInClasses":["org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, {"i18nKey":"timesheet.recenttasks.select","bundleName":"I18nResources","translation":"--- Recent structure elements ---","translationDE":"--- Zuletzt verwendete Strukturelemente ---","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"timesheet.reference","bundleName":"I18nResources","translation":"Reference","translationDE":"Referenz","usedInClasses":["org.projectforge.business.timesheet.TimesheetDO","org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, - {"i18nKey":"timesheet.reference.info","bundleName":"I18nResources","translation":"References may be used for grouping time sheets. Already used references for the same or any descendant structure element in time sheets also by other users can be easily used via auto-completion.","translationDE":"Referenzen können zur Gruppierung von Zeitberichten genutzt werden. Bereits benutzte Referenzen in Zeitberichten in der Hierarchie des Strukturelements (auch von anderen Usern) können per Autovervollständigung genutzt werden.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, + {"i18nKey":"timesheet.reference","bundleName":"I18nResources","translation":"Reference","translationDE":"Referenz","usedInClasses":["org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, + {"i18nKey":"timesheet.reference.info","bundleName":"I18nResources","translation":"References may be used for grouping time sheets. Already used references for the same or any descendant structure element in time sheets also by other users can be easily used via auto-completion.","translationDE":"Referenzen können zur Gruppierung von Zeitberichten genutzt werden. Bereits benutzte Referenzen in Zeitberichten in der Hierarchie des Strukturelements (auch von anderen Usern) können per Autovervollständigung genutzt werden.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, {"i18nKey":"timesheet.signatureEmployee","bundleName":"I18nResources","translation":"Signature employee","translationDE":"Unterschrift Mitarbeiter:in","usedInClasses":["org.projectforge.web.fibu.MonthlyEmployeeReportPage"],"usedInFiles":[]}, {"i18nKey":"timesheet.signatureProjectLeader","bundleName":"I18nResources","translation":"Signature project leader","translationDE":"Unterschrift Projektmanagement","usedInClasses":["org.projectforge.web.fibu.MonthlyEmployeeReportPage"],"usedInFiles":[]}, {"i18nKey":"timesheet.startTime","bundleName":"I18nResources","translation":"Start time","translationDE":"Beginn","usedInClasses":["org.projectforge.business.timesheet.TimesheetDO","org.projectforge.web.humanresources.HRPlanningEditForm"],"usedInFiles":[]}, @@ -2389,10 +2443,10 @@ {"i18nKey":"timesheet.taskReference","bundleName":"I18nResources","translation":"Reference of element","translationDE":"Elementreferenz","usedInClasses":["org.projectforge.business.timesheet.TimesheetExport"],"usedInFiles":[]}, {"i18nKey":"timesheet.templates","bundleName":"I18nResources","translation":"Templates","translationDE":"Vorlagen","usedInClasses":["org.projectforge.rest.TimesheetPagesRest","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"timesheet.templates.migrationOfLegacy.button","bundleName":"I18nResources","translation":"Old templates ","translationDE":"Alte Vorlagen","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, - {"i18nKey":"timesheet.templates.migrationOfLegacy.confirmationMessage","bundleName":"I18nResources","translation":"Do you want to import your old templates from the classical version now? Any existing entry will not be overwritten.","translationDE":"Sollen alte Vorlagen jetzt übernommen werden? Vorhandene Vorlagen werden nicht überschrieben.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, - {"i18nKey":"timesheet.templates.migrationOfLegacy.tooltip","bundleName":"I18nResources","translation":"Imports old templates of classical version.","translationDE":"Übernehmen alter Vorlagen der klassischen Version.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, + {"i18nKey":"timesheet.templates.migrationOfLegacy.confirmationMessage","bundleName":"I18nResources","translation":"Do you want to import your old templates from the classical version now? Any existing entry will not be overwritten.","translationDE":"Sollen alte Vorlagen jetzt übernommen werden? Vorhandene Vorlagen werden nicht überschrieben.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, + {"i18nKey":"timesheet.templates.migrationOfLegacy.tooltip","bundleName":"I18nResources","translation":"Imports old templates of classical version.","translationDE":"Übernehmen alter Vorlagen der klassischen Version.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, {"i18nKey":"timesheet.templates.new","bundleName":"I18nResources","translation":"New template","translationDE":"Neue Vorlage","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, - {"i18nKey":"timesheet.templates.new.tooltip","bundleName":"I18nResources","translation":"You may create a new template by filling out this form and save it here by name.","translationDE":"Du kannst dieses Formular ausfüllen und anschließend als Vorlage definieren, indem du hier einen Namen vergibst.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, + {"i18nKey":"timesheet.templates.new.tooltip","bundleName":"I18nResources","translation":"You may create a new template by filling out this form and save it here by name.","translationDE":"Du kannst dieses Formular ausfüllen und anschließend als Vorlage definieren, indem du hier einen Namen vergibst.","usedInClasses":["org.projectforge.rest.TimesheetPagesRest"],"usedInFiles":[]}, {"i18nKey":"timesheet.timesheets","bundleName":"I18nResources","translation":"Time sheets","translationDE":"Zeitberichte","usedInClasses":["org.projectforge.business.timesheet.TimesheetExport","org.projectforge.rest.calendar.CalendarSubscriptionInfoPageRest","org.projectforge.rest.pub.CalendarSubscriptionServiceRest","org.projectforge.web.teamcal.dialog.TeamCalFilterDialog"],"usedInFiles":[]}, {"i18nKey":"timesheet.title.add","bundleName":"I18nResources","translation":"New time sheet","translationDE":"Neuer Zeitbericht","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"timesheet.title.edit","bundleName":"I18nResources","translation":"Edit time sheet","translationDE":"Zeitbericht bearbeiten","usedInClasses":["org.projectforge.web.timesheet.TimesheetEditPage","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, @@ -2403,45 +2457,45 @@ {"i18nKey":"timestamp","bundleName":"I18nResources","translation":"Time stamp","translationDE":"Zeitstempel","usedInClasses":["org.projectforge.common.logging.LoggingEventData","org.projectforge.framework.persistence.database.HistoryMigrateService","org.projectforge.plugins.datatransfer.DataTransferAuditDao","org.projectforge.plugins.datatransfer.rest.DataTransferAuditPageRest","org.projectforge.rest.admin.LogViewerEvent","org.projectforge.rest.admin.LogViewerPageRest","org.projectforge.web.wicket.AbstractEditPage"],"usedInFiles":["./projectforge-business/src/main/resources/mail/mailHistoryTable.html"]}, {"i18nKey":"timezone","bundleName":"I18nResources","translation":"Time zone","translationDE":"Zeitzone","usedInClasses":["org.projectforge.framework.configuration.ConfigurationParam","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"tip","bundleName":"I18nResources","translation":"Tip","translationDE":"Tipp","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"title","bundleName":"I18nResources","translation":"Title","translationDE":"Titel","usedInClasses":["org.projectforge.business.address.AddressExport","org.projectforge.business.address.AddressbookDao","org.projectforge.business.gantt.GanttTaskImpl","org.projectforge.business.orga.ContractDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.task.TaskDO","org.projectforge.business.task.TaskDao","org.projectforge.business.task.TaskNode","org.projectforge.business.teamcal.admin.TeamCalDao","org.projectforge.framework.ToStringUtil","org.projectforge.framework.jobs.AbstractJob","org.projectforge.mail.SendMail","org.projectforge.plugins.marketing.AddressCampaignDO","org.projectforge.plugins.marketing.AddressCampaignEditForm","org.projectforge.plugins.marketing.AddressCampaignListPage","org.projectforge.plugins.marketing.rest.AddressCampaignPagesRest","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.AddressBookPagesRest","org.projectforge.rest.AddressPagesRest","org.projectforge.rest.BookPagesRest","org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.calendar.CalEventPagesRest","org.projectforge.rest.calendar.TeamEventPagesRest","org.projectforge.rest.fibu.AuftragPagesRest","org.projectforge.rest.orga.ContractPagesRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.web.address.AddressPageSupport","org.projectforge.web.admin.AdminPage","org.projectforge.web.calendar.MyFullCalendarConfig","org.projectforge.web.fibu.AuftragsPositionFormComponent","org.projectforge.web.fibu.MonthlyEmployeeReportPage","org.projectforge.web.fibu.ReportObjectivesPanel","org.projectforge.web.gantt.GanttChartEditForm","org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.gantt.GanttTreeTableNode","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskSelectAutoCompleteFormComponent","org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage","org.projectforge.web.teamcal.event.TeamEventEditForm","org.projectforge.web.wicket.I18nParamMap","org.projectforge.web.wicket.WicketUtils","org.projectforge.web.wicket.flowlayout.ButtonPanel"],"usedInFiles":["./projectforge-business/src/main/resources/mail/mailOpening.html","./projectforge-business/src/main/resources/mail/orderChangeNotification.html","./projectforge-business/src/main/resources/mail/todoChangeNotification.html","./projectforge-business/src/main/resources/mail/vacationMail.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/ReportObjectivesPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/gantt/GanttChartEditTreeTablePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/ButtonPanel.html"]}, - {"i18nKey":"tooltip.accesskey.addEntry","bundleName":"I18nResources","translation":"dependent of the used browser: press CTRL-N, ALT-N, ALT-Shift-N etc.","translationDE":"Je nach Browser: STRG-N, ALT-N, ALT-Shift-N etc. drücken","usedInClasses":["org.projectforge.web.wicket.WebConstants"],"usedInFiles":[]}, - {"i18nKey":"tooltip.accesskey.addEntry.title","bundleName":"I18nResources","translation":"Access key N","translationDE":"Tastaturkürzel N","usedInClasses":["org.projectforge.web.wicket.WebConstants"],"usedInFiles":[]}, - {"i18nKey":"tooltip.assign","bundleName":"I18nResources","translation":"Assign selected elements","translationDE":"Selektierte Einträge zuweisen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.autocomplete.language","bundleName":"I18nResources","translation":"Double click shows you all used languages in the data base (by all users) for selection.","translationDE":"Über einen Doppelklick auf das Feld werden auch alle von allen Benutzer:innen bisher verwendeten Sprachen angezeigt.","usedInClasses":["org.projectforge.web.address.AddressPageSupport"],"usedInFiles":[]}, - {"i18nKey":"tooltip.autocomplete.recentSearchTerms","bundleName":"I18nResources","translation":"Double click on the text field will display the recent search terms for selection.","translationDE":"Über einen Doppelklick auf das Feld werden die zuletzt verwendeten Suchausdrücke zur Auswahl angezeigt.","usedInClasses":["org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, - {"i18nKey":"tooltip.autocomplete.timeZone","bundleName":"I18nResources","translation":"Double click shows you all used time zones in the data base (by all users) for selection.","translationDE":"Über einen Doppelklick auf das Feld werden auch alle von allen Benutzer:innen bisher verwendeten Zeitzonen angezeigt.","usedInClasses":["org.projectforge.web.user.UserEditForm","org.projectforge.web.wicket.components.TimeZoneField","org.projectforge.web.wicket.components.TimeZonePanel"],"usedInFiles":[]}, - {"i18nKey":"tooltip.autocomplete.withDblClickFunction","bundleName":"I18nResources","translation":"Double click on the text field will display the favorite entries for selection.","translationDE":"Über einen Doppelklick auf das Feld werden die Favoriten zur Auswahl angezeigt.","usedInClasses":["org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, - {"i18nKey":"tooltip.autocompletion.title","bundleName":"I18nResources","translation":"Auto-completion","translationDE":"Autovervollständigung","usedInClasses":["org.projectforge.web.address.AddressPageSupport","org.projectforge.web.address.PhoneCallForm"],"usedInFiles":[]}, + {"i18nKey":"title","bundleName":"I18nResources","translation":"Title","translationDE":"Titel","usedInClasses":["org.projectforge.business.address.AddressExport","org.projectforge.business.address.AddressbookDao","org.projectforge.business.gantt.GanttTaskImpl","org.projectforge.business.orga.ContractDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.poll.PollDO","org.projectforge.business.task.TaskDO","org.projectforge.business.task.TaskDao","org.projectforge.business.task.TaskNode","org.projectforge.business.teamcal.admin.TeamCalDao","org.projectforge.framework.ToStringUtil","org.projectforge.framework.jobs.AbstractJob","org.projectforge.mail.SendMail","org.projectforge.plugins.marketing.AddressCampaignDO","org.projectforge.plugins.marketing.AddressCampaignEditForm","org.projectforge.plugins.marketing.AddressCampaignListPage","org.projectforge.plugins.marketing.rest.AddressCampaignPagesRest","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.AddressBookPagesRest","org.projectforge.rest.AddressPagesRest","org.projectforge.rest.BookPagesRest","org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.calendar.CalEventPagesRest","org.projectforge.rest.calendar.TeamEventPagesRest","org.projectforge.rest.fibu.AuftragPagesRest","org.projectforge.rest.orga.ContractPagesRest","org.projectforge.rest.poll.PollInfoPageRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.rest.task.TaskPagesRest","org.projectforge.rest.task.TaskServicesRest","org.projectforge.web.address.AddressPageSupport","org.projectforge.web.admin.AdminPage","org.projectforge.web.calendar.MyFullCalendarConfig","org.projectforge.web.fibu.AuftragsPositionFormComponent","org.projectforge.web.fibu.MonthlyEmployeeReportPage","org.projectforge.web.fibu.ReportObjectivesPanel","org.projectforge.web.gantt.GanttChartEditForm","org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.gantt.GanttTreeTableNode","org.projectforge.web.task.TaskEditForm","org.projectforge.web.task.TaskListPage","org.projectforge.web.task.TaskSelectAutoCompleteFormComponent","org.projectforge.web.teamcal.admin.TeamCalEditForm","org.projectforge.web.teamcal.admin.TeamCalListPage","org.projectforge.web.teamcal.event.TeamEventEditForm","org.projectforge.web.wicket.I18nParamMap","org.projectforge.web.wicket.WicketUtils","org.projectforge.web.wicket.flowlayout.ButtonPanel"],"usedInFiles":["./projectforge-business/src/main/resources/mail/mailOpening.html","./projectforge-business/src/main/resources/mail/orderChangeNotification.html","./projectforge-business/src/main/resources/mail/todoChangeNotification.html","./projectforge-business/src/main/resources/mail/vacationMail.html","./projectforge-wicket/src/main/java/org/projectforge/web/fibu/ReportObjectivesPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/gantt/GanttChartEditTreeTablePanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/wicket/flowlayout/ButtonPanel.html"]}, + {"i18nKey":"tooltip.accesskey.addEntry","bundleName":"I18nResources","translation":"dependent of the used browser: press CTRL-N, ALT-N, ALT-Shift-N etc.","translationDE":"Je nach Browser: STRG-N, ALT-N, ALT-Shift-N etc. drücken","usedInClasses":["org.projectforge.web.wicket.WebConstants"],"usedInFiles":[]}, + {"i18nKey":"tooltip.accesskey.addEntry.title","bundleName":"I18nResources","translation":"Access key N","translationDE":"Tastaturkürzel N","usedInClasses":["org.projectforge.web.wicket.WebConstants"],"usedInFiles":[]}, + {"i18nKey":"tooltip.assign","bundleName":"I18nResources","translation":"Assign selected elements","translationDE":"Selektierte Einträge zuweisen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.autocomplete.language","bundleName":"I18nResources","translation":"Double click shows you all used languages in the data base (by all users) for selection.","translationDE":"Über einen Doppelklick auf das Feld werden auch alle von allen Benutzer:innen bisher verwendeten Sprachen angezeigt.","usedInClasses":["org.projectforge.web.address.AddressPageSupport"],"usedInFiles":[]}, + {"i18nKey":"tooltip.autocomplete.recentSearchTerms","bundleName":"I18nResources","translation":"Double click on the text field will display the recent search terms for selection.","translationDE":"Über einen Doppelklick auf das Feld werden die zuletzt verwendeten Suchausdrücke zur Auswahl angezeigt.","usedInClasses":["org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, + {"i18nKey":"tooltip.autocomplete.timeZone","bundleName":"I18nResources","translation":"Double click shows you all used time zones in the data base (by all users) for selection.","translationDE":"Über einen Doppelklick auf das Feld werden auch alle von allen Benutzer:innen bisher verwendeten Zeitzonen angezeigt.","usedInClasses":["org.projectforge.web.user.UserEditForm","org.projectforge.web.wicket.components.TimeZoneField","org.projectforge.web.wicket.components.TimeZonePanel"],"usedInFiles":[]}, + {"i18nKey":"tooltip.autocomplete.withDblClickFunction","bundleName":"I18nResources","translation":"Double click on the text field will display the favorite entries for selection.","translationDE":"Über einen Doppelklick auf das Feld werden die Favoriten zur Auswahl angezeigt.","usedInClasses":["org.projectforge.web.timesheet.TimesheetPageSupport"],"usedInFiles":[]}, + {"i18nKey":"tooltip.autocompletion.title","bundleName":"I18nResources","translation":"Auto-completion","translationDE":"Autovervollständigung","usedInClasses":["org.projectforge.web.address.AddressPageSupport","org.projectforge.web.address.PhoneCallForm"],"usedInFiles":[]}, {"i18nKey":"tooltip.cancel","bundleName":"I18nResources","translation":"Cancel","translationDE":"Abbrechen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.entry.delete","bundleName":"I18nResources","translation":"Delete entry","translationDE":"Eintrag löschen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.entry.markAsDeleted","bundleName":"I18nResources","translation":"Mark entry as deleted","translationDE":"Eintrag als gelöscht markieren","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.entry.delete","bundleName":"I18nResources","translation":"Delete entry","translationDE":"Eintrag löschen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.entry.markAsDeleted","bundleName":"I18nResources","translation":"Mark entry as deleted","translationDE":"Eintrag als gelöscht markieren","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tooltip.entry.undelete","bundleName":"I18nResources","translation":"Undelete entry","translationDE":"Eintrag wiederherstellen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tooltip.export.excel","bundleName":"I18nResources","translation":"Export as Excel file","translationDE":"Export im Excelformat","usedInClasses":["org.projectforge.web.fibu.AuftragListPage","org.projectforge.web.fibu.Kost1ListPage","org.projectforge.web.fibu.Kost2ListPage","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.wicket.AbstractListPage"],"usedInFiles":[]}, {"i18nKey":"tooltip.export.pdf","bundleName":"I18nResources","translation":"Export as pdf","translationDE":"Export als pdf","usedInClasses":["org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"tooltip.hideBirthdays","bundleName":"I18nResources","translation":"Hide birthdays","translationDE":"Geburtstage ausblenden","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.jiraSupport.field.content","bundleName":"I18nResources","translation":"JIRA issues are supported by this field, therefore JIRA issues such as PROJECTFORGE-123 will be displayed as a link to JIRA.","translationDE":"Es werden JIRA-Issues von diesem Feld unterstützt, d. h. JIRA-Issues der Form PROJECTFORGE-123 werden als JIRA-Link angezeigt.","usedInClasses":["org.projectforge.ui.JiraSupport","org.projectforge.web.wicket.WicketUtils"],"usedInFiles":[]}, + {"i18nKey":"tooltip.jiraSupport.field.content","bundleName":"I18nResources","translation":"JIRA issues are supported by this field, therefore JIRA issues such as PROJECTFORGE-123 will be displayed as a link to JIRA.","translationDE":"Es werden JIRA-Issues von diesem Feld unterstützt, d. h. JIRA-Issues der Form PROJECTFORGE-123 werden als JIRA-Link angezeigt.","usedInClasses":["org.projectforge.ui.JiraSupport","org.projectforge.web.wicket.WicketUtils"],"usedInFiles":[]}, {"i18nKey":"tooltip.jiraSupport.field.title","bundleName":"I18nResources","translation":"JIRA-Support","translationDE":"JIRA-Support","usedInClasses":["org.projectforge.web.wicket.WicketUtils"],"usedInFiles":[]}, {"i18nKey":"tooltip.lucene.link","bundleName":"I18nResources","translation":"Link to howto of lucene queries.","translationDE":"Link zur Lucene-Abfrage-Syntax.","usedInClasses":["org.projectforge.web.task.TaskTreeForm","org.projectforge.web.wicket.AbstractListForm"],"usedInFiles":[]}, - {"i18nKey":"tooltip.popups.mustBeAllowed","bundleName":"I18nResources","translation":"Please note: pop-ups must be allowed in your browser for this feature.","translationDE":"Bitte beachten: Für diese Funktion müssen Popups in Ihrem Browser erlaubt sein.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.popups.mustBeAllowed","bundleName":"I18nResources","translation":"Please note: pop-ups must be allowed in your browser for this feature.","translationDE":"Bitte beachten: Für diese Funktion müssen Popups in Ihrem Browser erlaubt sein.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tooltip.reload","bundleName":"I18nResources","translation":"Reload","translationDE":"Neu laden","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.selectBirthday","bundleName":"I18nResources","translation":"Select birthday","translationDE":"Geburtstag wählen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.selectDate","bundleName":"I18nResources","translation":"Select date","translationDE":"Datum wählen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.selectDateOrPeriod","bundleName":"I18nResources","translation":"Select date or time period","translationDE":"Datum oder Zeitraum wählen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.selectGroup","bundleName":"I18nResources","translation":"Select group","translationDE":"Gruppe wählen","usedInClasses":["org.projectforge.web.user.GroupSelectPanel","org.projectforge.web.user.NewGroupSelectPanel"],"usedInFiles":[]}, + {"i18nKey":"tooltip.selectBirthday","bundleName":"I18nResources","translation":"Select birthday","translationDE":"Geburtstag wählen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.selectDate","bundleName":"I18nResources","translation":"Select date","translationDE":"Datum wählen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.selectDateOrPeriod","bundleName":"I18nResources","translation":"Select date or time period","translationDE":"Datum oder Zeitraum wählen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.selectGroup","bundleName":"I18nResources","translation":"Select group","translationDE":"Gruppe wählen","usedInClasses":["org.projectforge.web.user.GroupSelectPanel","org.projectforge.web.user.NewGroupSelectPanel"],"usedInFiles":[]}, {"i18nKey":"tooltip.selectMe","bundleName":"I18nResources","translation":"You are great!","translationDE":"You are great!","usedInClasses":["org.projectforge.plugins.datatransfer.rest.DataTransferPersonalBoxPageRest","org.projectforge.rest.calendar.CalendarFilterServicesRest","org.projectforge.rest.core.AbstractPagesRest","org.projectforge.web.user.UserSelectPanel"],"usedInFiles":[]}, - {"i18nKey":"tooltip.selectTask","bundleName":"I18nResources","translation":"Select structure element","translationDE":"Strukturelement wählen","usedInClasses":["org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.task.TaskSelectPanel"],"usedInFiles":[]}, - {"i18nKey":"tooltip.selectUser","bundleName":"I18nResources","translation":"Select user","translationDE":"Benutzer:in wählen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.unassign","bundleName":"I18nResources","translation":"Unassign selected elements","translationDE":"Zuweisung für selektierte Einträge aufheben","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.selectTask","bundleName":"I18nResources","translation":"Select structure element","translationDE":"Strukturelement wählen","usedInClasses":["org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.task.TaskSelectPanel"],"usedInFiles":[]}, + {"i18nKey":"tooltip.selectUser","bundleName":"I18nResources","translation":"Select user","translationDE":"Benutzer:in wählen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.unassign","bundleName":"I18nResources","translation":"Unassign selected elements","translationDE":"Zuweisung für selektierte Einträge aufheben","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tooltip.unselect","bundleName":"I18nResources","translation":"Unselect item","translationDE":"Auswahl aufheben","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tooltip.unselectBirthday","bundleName":"I18nResources","translation":"Unselect birthday","translationDE":"Geburtstag löschen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tooltip.unselectBirthday","bundleName":"I18nResources","translation":"Unselect birthday","translationDE":"Geburtstag löschen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tooltip.unselectDate","bundleName":"I18nResources","translation":"Unselect date","translationDE":"Datumswahl aufheben","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tooltip.unselectGroup","bundleName":"I18nResources","translation":"Unselect group","translationDE":"Gruppenauswahl aufheben","usedInClasses":["org.projectforge.web.user.GroupSelectPanel","org.projectforge.web.user.NewGroupSelectPanel"],"usedInFiles":[]}, {"i18nKey":"tooltip.unselectTask","bundleName":"I18nResources","translation":"Unselect structure element","translationDE":"Strukturelementwahl aufheben","usedInClasses":["org.projectforge.web.gantt.GanttChartEditTreeTablePanel","org.projectforge.web.task.TaskSelectPanel"],"usedInFiles":[]}, {"i18nKey":"tooltip.unselectUser","bundleName":"I18nResources","translation":"Unselect user","translationDE":"Benutzer:innenwahl aufheben","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"totalSum","bundleName":"I18nResources","translation":"Total sum","translationDE":"Gesamtsumme","usedInClasses":["org.projectforge.plugins.liquidityplanning.LiquidityEntryListForm"],"usedInFiles":[]}, - {"i18nKey":"tutorial.expectedGroupNotFound","bundleName":"I18nResources","translation":"The expected group ''{0}'' doesn''t exist. Can''t process this tutorial request.","translationDE":"Die benötigte Gruppe ''{0}'' ist noch nicht angelegt. Die Tutorialanfrage kann deshalb nicht bearbeitet werden.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tutorial.expectedTaskNotFound","bundleName":"I18nResources","translation":"The expected task ''{0}'' doesn''t exist. Can''t process this tutorial request.","translationDE":"Das benötigte Strukturelement ''{0}'' ist noch nicht angelegt. Die Tutorialanfrage kann deshalb nicht bearbeitet werden.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"tutorial.expectedUserNotFound","bundleName":"I18nResources","translation":"The expected user ''{0}'' doesn''t exist. Can''t process this tutorial request.","translationDE":"Der benötigte Benutzer ''{0}'' ist noch nicht angelegt. Die Tutorialanfrage kann deshalb nicht bearbeitet werden.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tutorial.expectedGroupNotFound","bundleName":"I18nResources","translation":"The expected group ''{0}'' doesn''t exist. Can''t process this tutorial request.","translationDE":"Die benötigte Gruppe ''{0}'' ist noch nicht angelegt. Die Tutorialanfrage kann deshalb nicht bearbeitet werden.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tutorial.expectedTaskNotFound","bundleName":"I18nResources","translation":"The expected task ''{0}'' doesn''t exist. Can''t process this tutorial request.","translationDE":"Das benötigte Strukturelement ''{0}'' ist noch nicht angelegt. Die Tutorialanfrage kann deshalb nicht bearbeitet werden.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"tutorial.expectedUserNotFound","bundleName":"I18nResources","translation":"The expected user ''{0}'' doesn''t exist. Can''t process this tutorial request.","translationDE":"Der benötigte Benutzer ''{0}'' ist noch nicht angelegt. Die Tutorialanfrage kann deshalb nicht bearbeitet werden.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tutorial.objectAlreadyCreated","bundleName":"I18nResources","translation":"Can't process this tutorial request, the requested object does already exist.","translationDE":"Die Tutorialanfrage kann nicht bearbeitet werden, da das angefragte Objekt bereits existiert.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"tutorial.unknown","bundleName":"I18nResources","translation":"Can't process this tutorial request.","translationDE":"Die Tutorialanfrage kann nicht bearbeitet werden.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"unassign","bundleName":"I18nResources","translation":"Unassign","translationDE":"Entfernen","usedInClasses":[],"usedInFiles":[]}, @@ -2455,47 +2509,47 @@ {"i18nKey":"updateAndNext","bundleName":"I18nResources","translation":"Update and next","translationDE":"Ändern und nächster","usedInClasses":["org.projectforge.web.wicket.AbstractEditForm"],"usedInFiles":[]}, {"i18nKey":"upload","bundleName":"I18nResources","translation":"Upload","translationDE":"Hochladen","usedInClasses":["org.projectforge.framework.jcr.AttachmentsEventType","org.projectforge.plugins.eed.wicket.EmployeeBillingImportForm","org.projectforge.plugins.eed.wicket.EmployeeSalaryImportForm","org.projectforge.web.teamcal.event.importics.TeamCalImportForm","org.projectforge.web.wicket.flowlayout.IconType"],"usedInFiles":["./projectforge-wicket/src/main/java/org/projectforge/web/admin/SetupPage.html"]}, {"i18nKey":"uptodate","bundleName":"I18nResources","translation":"up-to-date","translationDE":"aktuell","usedInClasses":["org.projectforge.business.address.AddressStatus","org.projectforge.favorites.Favorites","org.projectforge.plugins.licensemanagement.LicenseStatus","org.projectforge.web.address.AddressListForm"],"usedInFiles":[]}, - {"i18nKey":"user","bundleName":"I18nResources","translation":"User","translationDE":"Benutzer:in","usedInClasses":["org.projectforge.business.humanresources.HRPlanningDao","org.projectforge.business.humanresources.HRPlanningEntryDao","org.projectforge.business.scripting.ScriptParameterType","org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.timesheet.TimesheetDao","org.projectforge.business.timesheet.TimesheetExport","org.projectforge.business.user.UserFavorite","org.projectforge.business.user.UserPrefDOXmlDumpHook","org.projectforge.business.user.UserRightDao","org.projectforge.framework.access.AccessException","org.projectforge.framework.jobs.AbstractJob","org.projectforge.framework.persistence.DaoConst","org.projectforge.framework.persistence.database.json.DatabaseWriter","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO","org.projectforge.framework.persistence.user.entities.UserPasswordDO","org.projectforge.framework.persistence.user.entities.UserPrefXmlBeforePersistListener","org.projectforge.menu.builder.MenuItemDefId","org.projectforge.plugins.datatransfer.rest.DataTransferPersonalBoxPageRest","org.projectforge.plugins.eed.excelimport.EmployeeBillingExcelImporter","org.projectforge.plugins.eed.wicket.EmployeeListEditPage","org.projectforge.registry.Registry","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.CardDAVInfoPageRest","org.projectforge.rest.TimesheetMultiSelectedPageRest","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.admin.LogViewerPageRest","org.projectforge.rest.fibu.EmployeePagesRest","org.projectforge.rest.hr.HRPlanningPagesRest","org.projectforge.rest.pub.CalendarSubscriptionServiceRest","org.projectforge.security.dto.WebAuthnPublicKeyCredentialCreationOptions","org.projectforge.ui.AutoCompletion","org.projectforge.web.access.AccessListForm","org.projectforge.web.calendar.CalendarPageSupport","org.projectforge.web.core.NavTopPanel","org.projectforge.web.fibu.AuftragListForm","org.projectforge.web.fibu.EmployeeEditForm","org.projectforge.web.fibu.MonthlyEmployeeReportForm","org.projectforge.web.fibu.MonthlyEmployeeReportPage","org.projectforge.web.humanresources.HRListPage","org.projectforge.web.humanresources.HRListResourceLinkPanel","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.humanresources.HRPlanningListForm","org.projectforge.web.rest.RestCalendarSubscriptionUserFilter","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetEditPage","org.projectforge.web.timesheet.TimesheetListForm","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.user.AttendeeWicketProvider","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserEditPage","org.projectforge.web.user.UserListPage","org.projectforge.web.user.UserPrefEditForm","org.projectforge.web.user.UserPrefListPage","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.AbstractListForm","org.projectforge.web.wicket.EditPageSupport","org.projectforge.web.wicket.flowlayout.IconType"],"usedInFiles":["./projectforge-business/src/main/resources/mail/mailHistoryTable.html","./projectforge-common/src/main/kotlin/org/projectforge/common/logging/LogConstants.kt","./projectforge-wicket/src/main/java/org/projectforge/web/core/NavTopPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/humanresources/HRListResourceLinkPanel.html"]}, - {"i18nKey":"user.My2FA.expired","bundleName":"I18nResources","translation":"For the requested action a 2FA is required not older than {0}.","translationDE":"Für die angeforderte Aktion ist eine (erneute) Zwei-Faktor-Authentifizierung erforderlich, die nicht älter als {0} ist.","usedInClasses":["org.projectforge.rest.my2fa.My2FAPageRest"],"usedInFiles":[]}, + {"i18nKey":"user","bundleName":"I18nResources","translation":"User","translationDE":"Benutzer:in","usedInClasses":["org.projectforge.business.humanresources.HRPlanningDao","org.projectforge.business.humanresources.HRPlanningEntryDao","org.projectforge.business.scripting.ScriptParameterType","org.projectforge.business.timesheet.TimesheetDO","org.projectforge.business.timesheet.TimesheetDao","org.projectforge.business.user.UserFavorite","org.projectforge.business.user.UserPrefDOXmlDumpHook","org.projectforge.business.user.UserRightDao","org.projectforge.framework.access.AccessException","org.projectforge.framework.jobs.AbstractJob","org.projectforge.framework.persistence.DaoConst","org.projectforge.framework.persistence.database.json.DatabaseWriter","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO","org.projectforge.framework.persistence.user.entities.UserPasswordDO","org.projectforge.framework.persistence.user.entities.UserPrefXmlBeforePersistListener","org.projectforge.menu.builder.MenuItemDefId","org.projectforge.plugins.datatransfer.rest.DataTransferPersonalBoxPageRest","org.projectforge.plugins.eed.excelimport.EmployeeBillingExcelImporter","org.projectforge.plugins.eed.wicket.EmployeeListEditPage","org.projectforge.registry.Registry","org.projectforge.renderer.custom.MicromataFormatter","org.projectforge.rest.CardDAVInfoPageRest","org.projectforge.rest.TimesheetMultiSelectedPageRest","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.admin.LogViewerPageRest","org.projectforge.rest.fibu.EmployeePagesRest","org.projectforge.rest.hr.HRPlanningPagesRest","org.projectforge.rest.poll.ResponsePageRest","org.projectforge.rest.pub.CalendarSubscriptionServiceRest","org.projectforge.security.dto.WebAuthnPublicKeyCredentialCreationOptions","org.projectforge.ui.AutoCompletion","org.projectforge.web.access.AccessListForm","org.projectforge.web.calendar.CalendarPageSupport","org.projectforge.web.core.NavTopPanel","org.projectforge.web.fibu.AuftragListForm","org.projectforge.web.fibu.EmployeeEditForm","org.projectforge.web.fibu.MonthlyEmployeeReportForm","org.projectforge.web.fibu.MonthlyEmployeeReportPage","org.projectforge.web.humanresources.HRListPage","org.projectforge.web.humanresources.HRListResourceLinkPanel","org.projectforge.web.humanresources.HRPlanningEditForm","org.projectforge.web.humanresources.HRPlanningListForm","org.projectforge.web.rest.RestCalendarSubscriptionUserFilter","org.projectforge.web.timesheet.TimesheetEditForm","org.projectforge.web.timesheet.TimesheetEditPage","org.projectforge.web.timesheet.TimesheetListForm","org.projectforge.web.timesheet.TimesheetListPage","org.projectforge.web.user.AttendeeWicketProvider","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserEditPage","org.projectforge.web.user.UserListPage","org.projectforge.web.user.UserPrefEditForm","org.projectforge.web.user.UserPrefListPage","org.projectforge.web.wicket.AbstractEditPage","org.projectforge.web.wicket.AbstractListForm","org.projectforge.web.wicket.EditPageSupport","org.projectforge.web.wicket.flowlayout.IconType"],"usedInFiles":["./projectforge-business/src/main/resources/mail/mailHistoryTable.html","./projectforge-common/src/main/kotlin/org/projectforge/common/logging/LogConstants.kt","./projectforge-wicket/src/main/java/org/projectforge/web/core/NavTopPanel.html","./projectforge-wicket/src/main/java/org/projectforge/web/humanresources/HRListResourceLinkPanel.html"]}, + {"i18nKey":"user.My2FA.expired","bundleName":"I18nResources","translation":"For the requested action a 2FA is required not older than {0}.","translationDE":"Für die angeforderte Aktion ist eine (erneute) Zwei-Faktor-Authentifizierung erforderlich, die nicht älter als {0} ist.","usedInClasses":["org.projectforge.rest.my2fa.My2FAPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.required","bundleName":"I18nResources","translation":"A (new) two factor authentication is required for proceeding.","translationDE":"Eine (erneute) Zwei-Faktor-Authentifizierung ist erforderlich.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest","org.projectforge.security.WebAuthnServicesRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.required.extended","bundleName":"I18nResources","translation":"A (new) two factor authentication is required for proceeding due to security reasons. You may request a code (see link below code field) or, if configured, use Your authenticator app.","translationDE":"Eine (erneute) Zwei-Faktor-Authentifizierung ist aus Sicherheitsgründen erforderlich. Du kannst hierzu einen Code anfordern (s. Link unterhalb des Code-Feldes) oder, falls konfiguriert, deine Authenticator-App benutzen.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.authenticator.info","bundleName":"I18nResources","translation":"### Setup your smart phone\n\n1. Scan this barcode in Your Authenticator-App.\n2. Done.\n\nEvery time ProjectForge requests a code, enter the displayed code in your Authenticator app.\n\nYou may setup others Authenticator apps on different devices as a backup, if you want.\n\nThe code displayed in your Authenticator app is valid for up to 30 seconds after disappearing in your app.","translationDE":"Smartphone einrichten\n\n1. Einfach den Barcode in der Authenticator-App scannen.\n2. Fertig.\n\nJedesmal, wenn ProjectForge nach einem Code fragt, einfach den in der Authenticator-App eingeblendeten Code verwenden.\n\nEs können mehrere Authenticator-Apps gleichzeitig (auch als Backup) genutzt werden.\n\nCodes aus der Authenticator-App sind noch für ca. 30 Sekunden gültig, nachdem sie in der App erneuert wurden.\n\nDiese Barcode-Ansicht ist für ca. 10 Minuten einsehbar. Anschließend wird für die erneute Anzeige eine 2FA-Authentifizierung benötigt.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.authenticator.intro","bundleName":"I18nResources","translation":"Please, use your 2FA Authenticator app, such as Microsoft or Google Authenticator as a second factor.","translationDE":"Für die Zwei-Faktor-Authentifzierung sollte eine Authenticator-App eingerichtet werden (z. B. Microsoft-, Google-Authenticator oder Fortitoken).","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.required.extended","bundleName":"I18nResources","translation":"A (new) two factor authentication is required for proceeding due to security reasons. You may request a code (see link below code field) or, if configured, use Your authenticator app.","translationDE":"Eine (erneute) Zwei-Faktor-Authentifizierung ist aus Sicherheitsgründen erforderlich. Du kannst hierzu einen Code anfordern (s. Link unterhalb des Code-Feldes) oder, falls konfiguriert, deine Authenticator-App benutzen.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.authenticator.info","bundleName":"I18nResources","translation":"### Setup your smart phone\n\n1. Scan this barcode in Your Authenticator-App.\n2. Done.\n\nEvery time ProjectForge requests a code, enter the displayed code in your Authenticator app.\n\nYou may setup others Authenticator apps on different devices as a backup, if you want.\n\nThe code displayed in your Authenticator app is valid for up to 30 seconds after disappearing in your app.","translationDE":"Smartphone einrichten\n\n1. Einfach den Barcode in der Authenticator-App scannen.\n2. Fertig.\n\nJedesmal, wenn ProjectForge nach einem Code fragt, einfach den in der Authenticator-App eingeblendeten Code verwenden.\n\nEs können mehrere Authenticator-Apps gleichzeitig (auch als Backup) genutzt werden.\n\nCodes aus der Authenticator-App sind noch für ca. 30 Sekunden gültig, nachdem sie in der App erneuert wurden.\n\nDiese Barcode-Ansicht ist für ca. 10 Minuten einsehbar. Anschließend wird für die erneute Anzeige eine 2FA-Authentifizierung benötigt.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.authenticator.intro","bundleName":"I18nResources","translation":"Please, use your 2FA Authenticator app, such as Microsoft or Google Authenticator as a second factor.","translationDE":"Für die Zwei-Faktor-Authentifzierung sollte eine Authenticator-App eingerichtet werden (z. B. Microsoft-, Google-Authenticator oder Fortitoken).","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.authenticator.title","bundleName":"I18nResources","translation":"Authenticator apps","translationDE":"Authenticator-Apps","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.authenticatorKey","bundleName":"I18nResources","translation":"Authenticator key","translationDE":"Authenticator-Schlüssel","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.check.fail","bundleName":"I18nResources","translation":"Code check failed.","translationDE":"Code-Prüfung fehlgeschlagen.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.check.success","bundleName":"I18nResources","translation":"Code checked successfully.","translationDE":"Code-Prüfung erfolgreich.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.authenticatorKey","bundleName":"I18nResources","translation":"Authenticator key","translationDE":"Authenticator-Schlüssel","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.check.fail","bundleName":"I18nResources","translation":"Code check failed.","translationDE":"Code-Prüfung fehlgeschlagen.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.check.success","bundleName":"I18nResources","translation":"Code checked successfully.","translationDE":"Code-Prüfung erfolgreich.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.disableAuthenticatorApp","bundleName":"I18nResources","translation":"Disable Authenticator app","translationDE":"Authenticator-App entfernen","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.disableAuthenticatorApp.confirmMessage","bundleName":"I18nResources","translation":"Do you want to disable or renew the token for Authenticator apps now? All Authenticator apps will be invalidated.","translationDE":"Soll die Authentificator-App nun entfernt bzw. erneuert werden? Alle bisherhigen Authentificator-Apps werden dann ungültig.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.disableAuthenticatorApp.info","bundleName":"I18nResources","translation":"Click this button to disable or renew Authentificator apps. A two-factor authentication not older than 2 minutes is required.","translationDE":"Diesen Knopf klicken, um die Authentificator-App zu entfernen oder zu erneuern. Für diese Funktion wird selber ein 2. FAktor benötigt, der nicht älter ist als 2 Minuten.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.disableAuthenticatorApp.confirmMessage","bundleName":"I18nResources","translation":"Do you want to disable or renew the token for Authenticator apps now? All Authenticator apps will be invalidated.","translationDE":"Soll die Authentificator-App nun entfernt bzw. erneuert werden? Alle bisherhigen Authentificator-Apps werden dann ungültig.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.disableAuthenticatorApp.info","bundleName":"I18nResources","translation":"Click this button to disable or renew Authentificator apps. A two-factor authentication not older than 2 minutes is required.","translationDE":"Diesen Knopf klicken, um die Authentificator-App zu entfernen oder zu erneuern. Für diese Funktion wird selber ein 2. FAktor benötigt, der nicht älter ist als 2 Minuten.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.enableAuthenticatorApp","bundleName":"I18nResources","translation":"Enable Authenticator app","translationDE":"Authentificator-Apps einrichten","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.enableAuthenticatorApp.confirmMessage","bundleName":"I18nResources","translation":"Do you want to setup an Authenticator apps? Afterwards a second factor is required on login. This operation is undoable.","translationDE":"Soll eine Authenticator-App nun eingerichtet werden? Anschließend wird für eine Anmeldung ein 2. Faktor benötigt. Diese Operation kann rückgängig gemacht werden.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.enableAuthenticatorApp.info","bundleName":"I18nResources","translation":"Click this button to setup an Authentificator app.","translationDE":"Hierüber kann eine Authenticator-App eingerichtet werden.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.info.1","bundleName":"I18nResources","translation":"### Second factor authentication (2FA)\n\n* ProjectForge supports 2FA for more security. Authenticator apps, mobile phones if texting is configured and/or e-mail are supported.\n* Every time ProjectForge requests a code, you may enter it from your Authenticator app or request a one-time-password by e-mail or as text message.\n\nPlease use the stay-logged-in functionality on login to prevent annoying 2FA requests!","translationDE":"### Zwei-Faktor-Authentifizierung (2FA)\n\n* ProjectForge unterstützt 2FA für eine erhöhte Sicherheit. Authenticator-Apps, SMS (wenn konfiguriert) und/oder E-Mails werden als 2. Faktor unterstützt.\n* Immer, wenn ProjectForge einen Code anfordert, kann ein Code aus der Authenticator-App eingegeben werden oder ein Einmalpasswort per E-Mail oder als SMS angefordert werden.\n\nWenn die Angemeldet-Bleiben-Funktion bei der Anmeldung verwendet wird, kann eine unnötig häufige Code-Abfrage vermieden werden!","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.info.2","bundleName":"I18nResources","translation":"It's highly recommended to configure a second factor via Authenticator App and/or WebAuthn (e. g. Fido2) and, if available a mobile phone number for a second factor via text messages.\n\nSome security relevant functionalities such as password reset are only available, if a second factor is configured (Authenticator-App, mobile phone or WebAuthn).","translationDE":"Es wird dringend empfohlen, einen zweiten Faktor über eine Authenticator-App und/oder WebAuthn (z. B. Fidu2) und, falls verfügbar, auch eine Mobilfunknummer zum Anfordern von Codes per SMS zu konfiguieren.\n\nEinige Sicherheitsfunktionen, wie z. B. ein Passwort-Reset, steht nur zur Verfügung, wenn mindestens ein 2. Faktor (Authenticator-App, SMS oder WebAuthn) konfiguriert ist.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.info.3","bundleName":"I18nResources","translation":"Feel free to test 2FA codes here. Modifications on this setup pages need a current 2FA authentification as well.","translationDE":"Hier können 2FA-Codes getestet werden. Außerdem benötigen Änderungen auf dieser Seite eine aktuelle 2FA-Prüfung.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.enableAuthenticatorApp.confirmMessage","bundleName":"I18nResources","translation":"Do you want to setup an Authenticator apps? Afterwards a second factor is required on login. This operation is undoable.","translationDE":"Soll eine Authenticator-App nun eingerichtet werden? Anschließend wird für eine Anmeldung ein 2. Faktor benötigt. Diese Operation kann rückgängig gemacht werden.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.enableAuthenticatorApp.info","bundleName":"I18nResources","translation":"Click this button to setup an Authentificator app.","translationDE":"Hierüber kann eine Authenticator-App eingerichtet werden.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.info.1","bundleName":"I18nResources","translation":"### Second factor authentication (2FA)\n\n* ProjectForge supports 2FA for more security. Authenticator apps, mobile phones if texting is configured and/or e-mail are supported.\n* Every time ProjectForge requests a code, you may enter it from your Authenticator app or request a one-time-password by e-mail or as text message.\n\nPlease use the stay-logged-in functionality on login to prevent annoying 2FA requests!","translationDE":"### Zwei-Faktor-Authentifizierung (2FA)\n\n* ProjectForge unterstützt 2FA für eine erhöhte Sicherheit. Authenticator-Apps, SMS (wenn konfiguriert) und/oder E-Mails werden als 2. Faktor unterstützt.\n* Immer, wenn ProjectForge einen Code anfordert, kann ein Code aus der Authenticator-App eingegeben werden oder ein Einmalpasswort per E-Mail oder als SMS angefordert werden.\n\nWenn die Angemeldet-Bleiben-Funktion bei der Anmeldung verwendet wird, kann eine unnötig häufige Code-Abfrage vermieden werden!","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.info.2","bundleName":"I18nResources","translation":"It's highly recommended to configure a second factor via Authenticator App and/or WebAuthn (e. g. Fido2) and, if available a mobile phone number for a second factor via text messages.\n\nSome security relevant functionalities such as password reset are only available, if a second factor is configured (Authenticator-App, mobile phone or WebAuthn).","translationDE":"Es wird dringend empfohlen, einen zweiten Faktor über eine Authenticator-App und/oder WebAuthn (z. B. Fidu2) und, falls verfügbar, auch eine Mobilfunknummer zum Anfordern von Codes per SMS zu konfiguieren.\n\nEinige Sicherheitsfunktionen, wie z. B. ein Passwort-Reset, steht nur zur Verfügung, wenn mindestens ein 2. Faktor (Authenticator-App, SMS oder WebAuthn) konfiguriert ist.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.info.3","bundleName":"I18nResources","translation":"Feel free to test 2FA codes here. Modifications on this setup pages need a current 2FA authentification as well.","translationDE":"Hier können 2FA-Codes getestet werden. Außerdem benötigen Änderungen auf dieser Seite eine aktuelle 2FA-Prüfung.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.info.title","bundleName":"I18nResources","translation":"Two factor authentication","translationDE":"Zweifaktorauthentifizierung","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.showAuthenticatorKey","bundleName":"I18nResources","translation":"Show authenticator key","translationDE":"Authenticator-Zugang anzeigen","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.sms.info","bundleName":"I18nResources","translation":"You may configure here your mobile phone number for receiving one time passwords on demand as text message.","translationDE":"Hier kann eine Mobilfunknummer hinterlegt werden, um einen 2. Faktor per SMS anzufordern.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.sms.info.title","bundleName":"I18nResources","translation":"SMS configuration","translationDE":"SMS-Konfiguration","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FA.setup.sms.mobileNumberRecommended","bundleName":"I18nResources","translation":"It's highly recommended to configure Your mobile number here as a second factor.\n\nYou may get a second factor as a text message as an alternative.\n\nIf you want to change Your mobile number, a (new) 2FA is required (see above).","translationDE":"Es wird dringend empfohlen, hier die eigene Mobilfunknummer anzugeben.\n\nÜber das Mobiltelefon kann ein zweiter Faktor als SMS alternativ angefordert werden.\n\nWenn die Mobilfunknummer geändert werden soll, wird eine (neue) Zweifaktorauthentifizierung benötigt (siehe oben).","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FA.setup.sms.mobileNumberRecommended","bundleName":"I18nResources","translation":"It's highly recommended to configure Your mobile number here as a second factor.\n\nYou may get a second factor as a text message as an alternative.\n\nIf you want to change Your mobile number, a (new) 2FA is required (see above).","translationDE":"Es wird dringend empfohlen, hier die eigene Mobilfunknummer anzugeben.\n\nÜber das Mobiltelefon kann ein zweiter Faktor als SMS alternativ angefordert werden.\n\nWenn die Mobilfunknummer geändert werden soll, wird eine (neue) Zweifaktorauthentifizierung benötigt (siehe oben).","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FA.setup.title","bundleName":"I18nResources","translation":"Setup of two-factor-authentication (2FA)","translationDE":"Zwei-Faktor-Authentifizierung (2FA) einrichten","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.authentification.info","bundleName":"I18nResources","translation":"A second factor is required for proceeding. Please enter any 2nd factor (e. g. OTP) you have (requested): from Your Authenticator-App or received by SMS or mail or you may use any WebAuthn token you have registered.","translationDE":"Ein zweiter Faktor ist nun erforderlich. Hier kann ein 2. Faktor (z. B. OTP-Einmalpasswort) eingegeben werden: Aus einer Authenticator-App, ein angeforderter Code per SMS oder E-Mail oder über einen registrierten WebAuthn-Token.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.authentification.info","bundleName":"I18nResources","translation":"A second factor is required for proceeding. Please enter any 2nd factor (e. g. OTP) you have (requested): from Your Authenticator-App or received by SMS or mail or you may use any WebAuthn token you have registered.","translationDE":"Ein zweiter Faktor ist nun erforderlich. Hier kann ein 2. Faktor (z. B. OTP-Einmalpasswort) eingegeben werden: Aus einer Authenticator-App, ein angeforderter Code per SMS oder E-Mail oder über einen registrierten WebAuthn-Token.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.code","bundleName":"I18nResources","translation":"Code","translationDE":"Code","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest","org.projectforge.security.My2FAData"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.code.info","bundleName":"I18nResources","translation":"Code from your authenticator app or the one time password (OTP) you received by e-mail of text message.","translationDE":"Code aus der Authenticator-App oder der Code (Einmalpasswort), welches per E-Mail oder SMS versendet wurde.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest","org.projectforge.security.My2FAData"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.code.validate","bundleName":"I18nResources","translation":"Validate","translationDE":"Prüfen","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.error.timePenalty.message","bundleName":"I18nResources","translation":"You have been blocked until {0} ({1}) after {2} failed code checks. Please note, that your account might be deactivated after {3} failed OTP checks.","translationDE":"Die Funktion ist aus Sicherheitsgründen blockiert bis {0} ({1}) nach {2} Fehlversuchen. Bitte beachten, dass dieser Account nach {3} Fehlversuchen gesperrt wird.","usedInClasses":["org.projectforge.security.My2FABruteForceProtection"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.error.validation","bundleName":"I18nResources","translation":"Code not correct or two-factor authentication not configured.","translationDE":"Code nicht gültig oder die Zweifaktor-Authentifizierung ist noch nicht eingerichtet.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.code.validate","bundleName":"I18nResources","translation":"Validate","translationDE":"Prüfen","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.error.timePenalty.message","bundleName":"I18nResources","translation":"You have been blocked until {0} ({1}) after {2} failed code checks. Please note, that your account might be deactivated after {3} failed OTP checks.","translationDE":"Die Funktion ist aus Sicherheitsgründen blockiert bis {0} ({1}) nach {2} Fehlversuchen. Bitte beachten, dass dieser Account nach {3} Fehlversuchen gesperrt wird.","usedInClasses":["org.projectforge.security.My2FABruteForceProtection"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.error.validation","bundleName":"I18nResources","translation":"Code not correct or two-factor authentication not configured.","translationDE":"Code nicht gültig oder die Zweifaktor-Authentifizierung ist noch nicht eingerichtet.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.lastSuccessful2FA","bundleName":"I18nResources","translation":"Last successful 2 FA","translationDE":"Letzte erfolgreiche 2. Faktorauthentifizierung","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.password.info","bundleName":"I18nResources","translation":"The password is only needed as an additional factor if you received the code via e-mail.","translationDE":"Das Password wird nur beim Versenden des Einmalpassworts per E-Mail aus Sicherheitsgründen verlangt.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.password.wrong","bundleName":"I18nResources","translation":"Password check failed.","translationDE":"Passwortprüfung fehlgeschlagen.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.password.info","bundleName":"I18nResources","translation":"The password is only needed as an additional factor if you received the code via e-mail.","translationDE":"Das Password wird nur beim Versenden des Einmalpassworts per E-Mail aus Sicherheitsgründen verlangt.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.password.wrong","bundleName":"I18nResources","translation":"Password check failed.","translationDE":"Passwortprüfung fehlgeschlagen.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.sendCode.mail","bundleName":"I18nResources","translation":"Request mail code","translationDE":"E-Mail-Code anfordern","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.sendCode.mail.info","bundleName":"I18nResources","translation":"Send code as e-mail. The code will be valid up to 2 minutes and your password is required when validating the sent code.","translationDE":"Code per E-Mail anfordern. Dieser Code ist bis zu 2 Minuten gültig.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.sendCode.mail.info","bundleName":"I18nResources","translation":"Send code as e-mail. The code will be valid up to 2 minutes and your password is required when validating the sent code.","translationDE":"Code per E-Mail anfordern. Dieser Code ist bis zu 2 Minuten gültig.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.sendCode.mail.message","bundleName":"I18nResources","translation":"Your code is: {0}","translationDE":"Der Code lautet: {0}","usedInClasses":["org.projectforge.web.My2FAHttpService"],"usedInFiles":["./projectforge-business/src/main/resources/mail/otpMail.html"]}, {"i18nKey":"user.My2FACode.sendCode.mail.sentSuccessfully","bundleName":"I18nResources","translation":"Mail was successfully sent to Your e-mail address at {0}","translationDE":"Der 2. Faktor wurde erfolgreich per E-Mail versendet um {0}","usedInClasses":["org.projectforge.web.My2FAHttpService"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.sendCode.mail.title","bundleName":"I18nResources","translation":"Message from ProjectForge","translationDE":"Nachricht von ProjectForge","usedInClasses":["org.projectforge.web.My2FAHttpService"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.sendCode.sms","bundleName":"I18nResources","translation":"Request SMS code","translationDE":"SMS-Code anfordern","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, - {"i18nKey":"user.My2FACode.sendCode.sms.info","bundleName":"I18nResources","translation":"Request code as text message to your mobile phone. The code will be valid up to 2 minutes.","translationDE":"Coder per SMS anfordern. Dieser Code ist bis zu 2 Minuten gültig.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, + {"i18nKey":"user.My2FACode.sendCode.sms.info","bundleName":"I18nResources","translation":"Request code as text message to your mobile phone. The code will be valid up to 2 minutes.","translationDE":"Coder per SMS anfordern. Dieser Code ist bis zu 2 Minuten gültig.","usedInClasses":["org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.sendCode.sms.sentSuccessfully","bundleName":"I18nResources","translation":"Message successfully sent to Your mobile phone at {0}.","translationDE":"Der 2. Faktor wurde erfolgreich per SMS versendet um {0}.","usedInClasses":["org.projectforge.web.My2FAHttpService"],"usedInFiles":[]}, {"i18nKey":"user.My2FACode.title","bundleName":"I18nResources","translation":"Two factor authentication","translationDE":"Zweifaktor-Authentifizierung","usedInClasses":["org.projectforge.rest.my2fa.My2FAPageRest","org.projectforge.rest.my2fa.My2FAServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.activated","bundleName":"I18nResources","translation":"Activated","translationDE":"Aktiviert","usedInClasses":["org.projectforge.rest.UserPagesStatusFilter","org.projectforge.rest.UserPagesStatusFilter$STATUS","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListForm","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, @@ -2504,46 +2558,46 @@ {"i18nKey":"user.adminUsers","bundleName":"I18nResources","translation":"Admin users","translationDE":"Administrator:innen","usedInClasses":["org.projectforge.rest.UserPagesTypeFilter","org.projectforge.rest.UserPagesTypeFilter$TYPE","org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, {"i18nKey":"user.adminUsers.none","bundleName":"I18nResources","translation":"Non-admin users","translationDE":"Nichtadministrator:innen","usedInClasses":["org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, {"i18nKey":"user.assignedGroups","bundleName":"I18nResources","translation":"Assigned groups","translationDE":"Assoziierte Gruppen","usedInClasses":["org.projectforge.rest.GroupAccessPagesRest","org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.authenticator_key","bundleName":"I18nResources","translation":"2FA authenticator key","translationDE":"Schlüssel für Zweifaktor-Authentifizierung","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.authenticator_key.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable for Authenticator clients for Two-factor-authentication with e. g. Microsoft-, Google-authenticator app or Fortitoken.","translationDE":"Dieser Schlüssel kann für die Zweifaktor-Authentifizierung z. B. über die Apps Microsoft-, Google Authenticator oder Fortitoken benutzt werden.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.authenticator_key","bundleName":"I18nResources","translation":"2FA authenticator key","translationDE":"Schlüssel für Zweifaktor-Authentifizierung","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.authenticator_key.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable for Authenticator clients for Two-factor-authentication with e. g. Microsoft-, Google-authenticator app or Fortitoken.","translationDE":"Dieser Schlüssel kann für die Zweifaktor-Authentifizierung z. B. über die Apps Microsoft-, Google Authenticator oder Fortitoken benutzt werden.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.authenticationToken.button.showUsage","bundleName":"I18nResources","translation":"Usage","translationDE":"Info","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.TokenInfoPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.button.showUsage.tooltip","bundleName":"I18nResources","translation":"Show usage of this token by clients.","translationDE":"Benutzung dieses Schüssels","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.TokenInfoPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.calendar_rest","bundleName":"I18nResources","translation":"Authentication token for calendars","translationDE":"Schlüssel für Kalenderexport","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.calendar_rest.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable ical exports of calendars and the user's time sheets.","translationDE":"Dieser persönliche Schlüssel kann zum Export/Abonnement von Kalendern oder Zeitberichten verwendet werden.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.dav_token","bundleName":"I18nResources","translation":"Authentication token for CalDav/CardDAV","translationDE":"Schlüssel für CalDav/CardDAV","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.dav_token.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable the CalDAV/CardDAV functionality of ProjectForge.","translationDE":"Dieser persönliche Schlüssel kann zur Benutzung der CardDAV/CalDAV-Funktion verwendet werden.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.button.showUsage.tooltip","bundleName":"I18nResources","translation":"Show usage of this token by clients.","translationDE":"Benutzung dieses Schüssels","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.TokenInfoPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.calendar_rest","bundleName":"I18nResources","translation":"Authentication token for calendars","translationDE":"Schlüssel für Kalenderexport","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.calendar_rest.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable ical exports of calendars and the user's time sheets.","translationDE":"Dieser persönliche Schlüssel kann zum Export/Abonnement von Kalendern oder Zeitberichten verwendet werden.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.dav_token","bundleName":"I18nResources","translation":"Authentication token for CalDav/CardDAV","translationDE":"Schlüssel für CalDav/CardDAV","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.dav_token.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable the CalDAV/CardDAV functionality of ProjectForge.","translationDE":"Dieser persönliche Schlüssel kann zur Benutzung der CardDAV/CalDAV-Funktion verwendet werden.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.authenticationToken.renew","bundleName":"I18nResources","translation":"Renew","translationDE":"Erneuern","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.renew.securityQuestion","bundleName":"I18nResources","translation":"Do you really want to renew the authentication token (this is irevocable)?","translationDE":"Soll der Schlüssel wirklich unwiderrufbar erneuert werden?","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.renew.successful","bundleName":"I18nResources","translation":"The authentication token is renewed and is now valid.","translationDE":"Der Schlüssel wurde erneuert und ist ab sofort gültig.","usedInClasses":["org.projectforge.rest.UserPagesRest","org.projectforge.rest.UserServicesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.renew.tooltip","bundleName":"I18nResources","translation":"You may renew this token if you are in doubt if your authentication is misused by any fraudster. If renewed any previous stored authentication key is invalid. Please note: This operation is irevocable.","translationDE":"Der Schlüssel kann erneuert werden, wenn der Verdacht auf einen möglichen Missbrauch vorliegt. Nach der Erneuerung sind vorher benutzte Schlüssel ungültig. Bitte beachten: Diese Operation ist unwiderruflich!","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.rest_client","bundleName":"I18nResources","translation":"Authentication token for rest clients","translationDE":"Schlüssel für Rest-Clients","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.rest_client.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable for rest clients if ProjectForge's password shouldn't be used there.","translationDE":"Dieser persönliche Schlüssel kann zur Benutzung in Rest-Clients verwendet werden, wenn das ProjectForge-Passwort dort nicht verwendet werden soll.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.stay_logged_in_key","bundleName":"I18nResources","translation":"Key for stay-logged-in functionality","translationDE":"Schlüssel für Angemeldet-Bleiben-Funktion","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, - {"i18nKey":"user.authenticationToken.stay_logged_in_key.tooltip","bundleName":"I18nResources","translation":"This personal key is used for stay-logged-in functionality in your browser and will stored as cookie. After renewing all your browser sessions are invalid and re-login is required.","translationDE":"Dieser persönliche Schlüssel wird für die Angemeldet-Bleiben-Funktion im Browser verwendet und als Cookie im Browser gespeichert. Durch Erneuern können alle Browsersitzungen beendet werden.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.renew.securityQuestion","bundleName":"I18nResources","translation":"Do you really want to renew the authentication token (this is irevocable)?","translationDE":"Soll der Schlüssel wirklich unwiderrufbar erneuert werden?","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.renew.successful","bundleName":"I18nResources","translation":"The authentication token is renewed and is now valid.","translationDE":"Der Schlüssel wurde erneuert und ist ab sofort gültig.","usedInClasses":["org.projectforge.rest.UserPagesRest","org.projectforge.rest.UserServicesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.renew.tooltip","bundleName":"I18nResources","translation":"You may renew this token if you are in doubt if your authentication is misused by any fraudster. If renewed any previous stored authentication key is invalid. Please note: This operation is irevocable.","translationDE":"Der Schlüssel kann erneuert werden, wenn der Verdacht auf einen möglichen Missbrauch vorliegt. Nach der Erneuerung sind vorher benutzte Schlüssel ungültig. Bitte beachten: Diese Operation ist unwiderruflich!","usedInClasses":["org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.rest_client","bundleName":"I18nResources","translation":"Authentication token for rest clients","translationDE":"Schlüssel für Rest-Clients","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.rest_client.tooltip","bundleName":"I18nResources","translation":"This authentication token is usable for rest clients if ProjectForge's password shouldn't be used there.","translationDE":"Dieser persönliche Schlüssel kann zur Benutzung in Rest-Clients verwendet werden, wenn das ProjectForge-Passwort dort nicht verwendet werden soll.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.stay_logged_in_key","bundleName":"I18nResources","translation":"Key for stay-logged-in functionality","translationDE":"Schlüssel für Angemeldet-Bleiben-Funktion","usedInClasses":["org.projectforge.framework.persistence.user.entities.UserAuthenticationsDO"],"usedInFiles":[]}, + {"i18nKey":"user.authenticationToken.stay_logged_in_key.tooltip","bundleName":"I18nResources","translation":"This personal key is used for stay-logged-in functionality in your browser and will stored as cookie. After renewing all your browser sessions are invalid and re-login is required.","translationDE":"Dieser persönliche Schlüssel wird für die Angemeldet-Bleiben-Funktion im Browser verwendet und als Cookie im Browser gespeichert. Durch Erneuern können alle Browsersitzungen beendet werden.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.changePassword.error.noCharacter","bundleName":"I18nResources","translation":"Password must have at minimum one letter.","translationDE":"Passwort muss mindestens einen Buchstaben haben.","usedInClasses":["org.projectforge.business.password.PasswordQualityServiceImpl"],"usedInFiles":[]}, {"i18nKey":"user.changePassword.error.noNonCharacter","bundleName":"I18nResources","translation":"Password must have at minimum one non-letter.","translationDE":"Passwort muss mindestens einen Nicht-Buchstaben haben.","usedInClasses":["org.projectforge.business.password.PasswordQualityServiceImpl"],"usedInFiles":[]}, {"i18nKey":"user.changePassword.error.notMinLength","bundleName":"I18nResources","translation":"Password must have at least {0} characters.","translationDE":"Passwort muss mindestens {0} Zeichen haben.","usedInClasses":["org.projectforge.business.password.PasswordQualityServiceImpl","org.projectforge.rest.AttachmentsServicesRest"],"usedInFiles":[]}, {"i18nKey":"user.changePassword.error.oldPasswdEqualsNew","bundleName":"I18nResources","translation":"New password should not be the same as the old one.","translationDE":"Neues Passwort darf nicht dem alten entsprechen.","usedInClasses":["org.projectforge.business.password.PasswordQualityServiceImpl"],"usedInFiles":[]}, {"i18nKey":"user.changePassword.error.oldPasswordWrong","bundleName":"I18nResources","translation":"Old password does not match.","translationDE":"Das alte Passwort wurde nicht korrekt eingegeben.","usedInClasses":["org.projectforge.business.user.service.UserService"],"usedInFiles":[]}, {"i18nKey":"user.changePassword.error.passwordQualityCheck","bundleName":"I18nResources","translation":"Password must have at least {0} characters and at minimum one letter and one non-letter character.","translationDE":"Passwort muss mindestens {0} Zeichen und sowohl mindestens einen Buchstaben als auch einen Nicht-Buchstaben enthalten.","usedInClasses":["org.projectforge.business.password.PasswordQualityServiceImpl"],"usedInFiles":[]}, - {"i18nKey":"user.changePassword.msg.passwordSuccessfullyChanged","bundleName":"I18nResources","translation":"Password successfully changed.","translationDE":"Passwort wurde erfolgreich geändert.","usedInClasses":["org.projectforge.rest.ChangePasswordPageRest","org.projectforge.rest.pub.PasswordResetPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.changePassword.msg.passwordSuccessfullyChanged","bundleName":"I18nResources","translation":"Password successfully changed.","translationDE":"Passwort wurde erfolgreich geändert.","usedInClasses":["org.projectforge.rest.ChangePasswordPageRest","org.projectforge.rest.pub.PasswordResetPageRest"],"usedInFiles":[]}, {"i18nKey":"user.changePassword.newPassword","bundleName":"I18nResources","translation":"New password","translationDE":"Neues Passwort","usedInClasses":["org.projectforge.rest.pub.PasswordResetPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.changePassword.notSupported","bundleName":"I18nResources","translation":"The change of password isn't supported. Please contact your administrator.","translationDE":"Die Passwortänderung wird nicht unterstützt. Kontaktieren Sie Ihre:n Administrator:in.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.changePassword.notSupported","bundleName":"I18nResources","translation":"The change of password isn't supported. Please contact your administrator.","translationDE":"Die Passwortänderung wird nicht unterstützt. Kontaktieren Sie Ihre:n Administrator:in.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.changePassword.oldPassword","bundleName":"I18nResources","translation":"Old password","translationDE":"Altes Passwort","usedInClasses":["org.projectforge.rest.ChangePasswordPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.changePassword.password.lastChange","bundleName":"I18nResources","translation":"Last change of password","translationDE":"Letzte Passwortänderung","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, - {"i18nKey":"user.changePassword.title","bundleName":"I18nResources","translation":"Change own password","translationDE":"Eigenes Passwort ändern","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.changePassword.password.lastChange","bundleName":"I18nResources","translation":"Last change of password","translationDE":"Letzte Passwortänderung","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, + {"i18nKey":"user.changePassword.title","bundleName":"I18nResources","translation":"Change own password","translationDE":"Eigenes Passwort ändern","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.changeWlanPassword.error.loginPasswordWrong","bundleName":"I18nResources","translation":"The login password is not correct.","translationDE":"Das Login-Passwort wurde nicht korrekt eingegeben.","usedInClasses":["org.projectforge.business.user.service.UserService"],"usedInFiles":[]}, - {"i18nKey":"user.changeWlanPassword.lastChange","bundleName":"I18nResources","translation":"Last change of WLAN/Samba password","translationDE":"Letzte WLAN/Samba-Passwortänderung","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, + {"i18nKey":"user.changeWlanPassword.lastChange","bundleName":"I18nResources","translation":"Last change of WLAN/Samba password","translationDE":"Letzte WLAN/Samba-Passwortänderung","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, {"i18nKey":"user.changeWlanPassword.loginPassword","bundleName":"I18nResources","translation":"Login password","translationDE":"Login-Passwort","usedInClasses":["org.projectforge.rest.ChangeWlanPasswordPageRest"],"usedInFiles":[]}, {"i18nKey":"user.changeWlanPassword.newPassword","bundleName":"I18nResources","translation":"New WLAN password","translationDE":"Neues WLAN-Passwort","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"user.changeWlanPassword.title","bundleName":"I18nResources","translation":"Change WLAN/Samba password","translationDE":"WLAN/Samba Passwort ändern","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.changeWlanPassword.title","bundleName":"I18nResources","translation":"Change WLAN/Samba password","translationDE":"WLAN/Samba Passwort ändern","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.deactivated","bundleName":"I18nResources","translation":"deactivated","translationDE":"Deaktiviert","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.rest.UserPagesRest","org.projectforge.rest.UserPagesStatusFilter","org.projectforge.rest.UserPagesStatusFilter$STATUS","org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, {"i18nKey":"user.defaultLocale","bundleName":"I18nResources","translation":"Default (browser)","translationDE":"Default (Browser)","usedInClasses":["org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.error.passwordAndRepeatDoesNotMatch","bundleName":"I18nResources","translation":"Password and password repeat does not match.","translationDE":"Passwort und Passwortwiederholung stimmen nicht überein.","usedInClasses":["org.projectforge.rest.ChangePasswordPageRest","org.projectforge.rest.pub.PasswordResetPageRest","org.projectforge.web.admin.SetupForm","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.error.passwordAndRepeatDoesNotMatch","bundleName":"I18nResources","translation":"Password and password repeat does not match.","translationDE":"Passwort und Passwortwiederholung stimmen nicht überein.","usedInClasses":["org.projectforge.rest.ChangePasswordPageRest","org.projectforge.rest.pub.PasswordResetPageRest","org.projectforge.web.admin.SetupForm","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.error.usernameAlreadyExists","bundleName":"I18nResources","translation":"User name already exists.","translationDE":"Benutzer:inname ist bereits vergeben.","usedInClasses":["org.projectforge.rest.UserPagesRest","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.filter.hrPlanning","bundleName":"I18nResources","translation":"HR planning","translationDE":"Personalplanung","usedInClasses":["org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, {"i18nKey":"user.filter.privileged","bundleName":"I18nResources","translation":"Privileged users","translationDE":"Privilegierte Benutzer:innen","usedInClasses":["org.projectforge.rest.UserPagesTypeFilter","org.projectforge.rest.UserPagesTypeFilter$TYPE"],"usedInFiles":[]}, - {"i18nKey":"user.filter.restricted","bundleName":"I18nResources","translation":"Restricted users","translationDE":"Eingeschränkte Benutzer:innen","usedInClasses":["org.projectforge.rest.UserPagesTypeFilter","org.projectforge.rest.UserPagesTypeFilter$TYPE"],"usedInFiles":[]}, + {"i18nKey":"user.filter.restricted","bundleName":"I18nResources","translation":"Restricted users","translationDE":"Eingeschränkte Benutzer:innen","usedInClasses":["org.projectforge.rest.UserPagesTypeFilter","org.projectforge.rest.UserPagesTypeFilter$TYPE"],"usedInFiles":[]}, {"i18nKey":"user.filter.status","bundleName":"I18nResources","translation":"State","translationDE":"Status","usedInClasses":["org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, {"i18nKey":"user.filter.syncStatus","bundleName":"I18nResources","translation":"Sync state","translationDE":"Synchronisationsstatus","usedInClasses":["org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, {"i18nKey":"user.filter.type","bundleName":"I18nResources","translation":"Type","translationDE":"Typ","usedInClasses":["org.projectforge.rest.UserPagesRest"],"usedInFiles":[]}, @@ -2552,67 +2606,67 @@ {"i18nKey":"user.hrPlanningEnabled.not","bundleName":"I18nResources","translation":"No HR planning","translationDE":"keine Personalplanung","usedInClasses":["org.projectforge.rest.UserPagesHRPlanningFilter","org.projectforge.rest.UserPagesHRPlanningFilter$PLANNING_TYPE","org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, {"i18nKey":"user.hrPlanningEnabled.tooltip","bundleName":"I18nResources","translation":"Should the user be available in HR planning?","translationDE":"Soll der oder die Benutzer:in in der Personalplanung sichtbar sein?","usedInClasses":["org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.jiraUsername","bundleName":"I18nResources","translation":"JIRA user name","translationDE":"JIRA Benutzer:inname","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.jiraUsername.tooltip","bundleName":"I18nResources","translation":"Only needed, if the ProjectForge user name differs from the JIRA user name and the user want to work with JIRA inside ProjectForge.","translationDE":"Wird nur gebraucht, wenn dieser von dem ProjectForge-Benutzer:innamen abweicht und der oder die Benutzer:in aus ProjectForge heraus mit JIRA arbeiten möchte.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.jiraUsername.tooltip","bundleName":"I18nResources","translation":"Only needed, if the ProjectForge user name differs from the JIRA user name and the user want to work with JIRA inside ProjectForge.","translationDE":"Wird nur gebraucht, wenn dieser von dem ProjectForge-Benutzer:innamen abweicht und der oder die Benutzer:in aus ProjectForge heraus mit JIRA arbeiten möchte.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.ldapValues","bundleName":"I18nResources","translation":"LDAP","translationDE":"LDAP","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, - {"i18nKey":"user.list.select.title","bundleName":"I18nResources","translation":"Select user","translationDE":"Benutzer:in auswählen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.list.select.title","bundleName":"I18nResources","translation":"Select user","translationDE":"Benutzer:in auswählen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.localUser","bundleName":"I18nResources","translation":"Local user","translationDE":"Lokale:r Benutzer:in","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.rest.UserPagesSyncFilter","org.projectforge.rest.UserPagesSyncFilter$Sync","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, {"i18nKey":"user.localUser.not","bundleName":"I18nResources","translation":"Common user","translationDE":"Allgemeine:r Benutzer:in","usedInClasses":["org.projectforge.rest.UserPagesSyncFilter","org.projectforge.rest.UserPagesSyncFilter$Sync","org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, {"i18nKey":"user.localUser.tooltip","bundleName":"I18nResources","translation":"Local users will not be synchronized with an external user management system (such as LDAP).","translationDE":"Lokale Benutzer:innen werden nicht mit einem externen Benutzer:innensystem synchronisiert (z. B. LDAP).","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.locale","bundleName":"I18nResources","translation":"Language","translationDE":"Sprache","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.menu.editRights","bundleName":"I18nResources","translation":"User rights","translationDE":"Benutzer:innenrechte","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.mobilePhone","bundleName":"I18nResources","translation":"Mobile phone","translationDE":"Mobilnummer","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.mobilePhone.info","bundleName":"I18nResources","translation":"Mobile phone usable as a 2nd factor (required e. g. for password reset or other services). You may configure this field by any admin or by configuring your two-factor-authentication.","translationDE":"Die Nummer kann als 2. Faktor benutzt werden, um z. B. das Passwort zurückzusetzen oder andere sicherheitsrelevante Bereiche zu nutzen. Die Nummer kann im Bereich Zwei-Faktor-Authentifizierung geändert werden.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.mobilePhone.invalidFormat","bundleName":"I18nResources","translation":"Valid characters for phone numbers are '+' as first char, '-', '/' and spaces. The leading country code is optional, e. g.: +49 561 316793-0 or 0561 316793-0","translationDE":"Es sind nur Zahlen sowie '+' am Anfang, '-', '/' und Leerzeichen erlaubt. Die führende Ländervorwahl ist optional. Beispiel: +49 561 316793-0 oder 0561 316793-0","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, - {"i18nKey":"user.myAccount.teamcalwhitelist","bundleName":"I18nResources","translation":"Calendar whitelist for calendar software","translationDE":"Kalender Whitelist für Kalendersoftware","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"user.mobilePhone.info","bundleName":"I18nResources","translation":"Mobile phone usable as a 2nd factor (required e. g. for password reset or other services). You may configure this field by any admin or by configuring your two-factor-authentication.","translationDE":"Die Nummer kann als 2. Faktor benutzt werden, um z. B. das Passwort zurückzusetzen oder andere sicherheitsrelevante Bereiche zu nutzen. Die Nummer kann im Bereich Zwei-Faktor-Authentifizierung geändert werden.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.mobilePhone.invalidFormat","bundleName":"I18nResources","translation":"Valid characters for phone numbers are '+' as first char, '-', '/' and spaces. The leading country code is optional, e. g.: +49 561 316793-0 or 0561 316793-0","translationDE":"Es sind nur Zahlen sowie '+' am Anfang, '-', '/' und Leerzeichen erlaubt. Die führende Ländervorwahl ist optional. Beispiel: +49 561 316793-0 oder 0561 316793-0","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"user.myAccount.teamcalwhitelist","bundleName":"I18nResources","translation":"Calendar whitelist for calendar software","translationDE":"Kalender Whitelist für Kalendersoftware","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.myAccount.title.edit","bundleName":"I18nResources","translation":"Edit my account","translationDE":"Mein Zugang","usedInClasses":["org.projectforge.rest.MyAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"user.panel.error.usernameNotFound","bundleName":"I18nResources","translation":"User name doesn't exist.","translationDE":"Benutzer:inname nicht existent.","usedInClasses":["org.projectforge.web.user.UserSelectPanel"],"usedInFiles":[]}, {"i18nKey":"user.personalPhoneIdentifiers","bundleName":"I18nResources","translation":"Phone ids","translationDE":"Telefonkennungen","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, - {"i18nKey":"user.personalPhoneIdentifiers.pleaseDefine","bundleName":"I18nResources","translation":"Define phone numbers under 'My account'.","translationDE":"Anschlüsse festlegen unter 'Mein Zugang'","usedInClasses":["org.projectforge.web.address.PhoneCallForm"],"usedInFiles":[]}, - {"i18nKey":"user.personalPhoneIdentifiers.tooltip.content","bundleName":"I18nResources","translation":"Define here your personal phone id's in your company (id = internal phone number). Multiple values should be comma separated. In address list you can choose your current phone for direct dialing by clicking on a phone number in the address list.","translationDE":"Hier können benutzerspezifische Telefon-Ids (= interne Rufnummer) als kommaseparierte Werte angegeben werden. In der Adressenliste kann somit eine Direktwahl von diesen Telefonen durch Klicken auf die gewünschte Rufnummer initiiert werden.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.personalPhoneIdentifiers.pleaseDefine","bundleName":"I18nResources","translation":"Define phone numbers under 'My account'.","translationDE":"Anschlüsse festlegen unter 'Mein Zugang'","usedInClasses":["org.projectforge.web.address.PhoneCallForm"],"usedInFiles":[]}, + {"i18nKey":"user.personalPhoneIdentifiers.tooltip.content","bundleName":"I18nResources","translation":"Define here your personal phone id's in your company (id = internal phone number). Multiple values should be comma separated. In address list you can choose your current phone for direct dialing by clicking on a phone number in the address list.","translationDE":"Hier können benutzerspezifische Telefon-Ids (= interne Rufnummer) als kommaseparierte Werte angegeben werden. In der Adressenliste kann somit eine Direktwahl von diesen Telefonen durch Klicken auf die gewünschte Rufnummer initiiert werden.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.personalPhoneIdentifiers.tooltip.title","bundleName":"I18nResources","translation":"Direct call","translationDE":"Direktwahl","usedInClasses":["org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, - {"i18nKey":"user.restricted","bundleName":"I18nResources","translation":"restricted","translationDE":"eingeschränkt","usedInClasses":["org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, - {"i18nKey":"user.restricted.not","bundleName":"I18nResources","translation":"not restricted","translationDE":"nicht eingeschränkt","usedInClasses":["org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, - {"i18nKey":"user.restrictedUser","bundleName":"I18nResources","translation":"Restricted user","translationDE":"Eingeschränkte:r Nutzer:in","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, - {"i18nKey":"user.restrictedUser.tooltip","bundleName":"I18nResources","translation":"A restricted user has only the ability to log-in and to change his password, but the user is synchronized with the external user management system.","translationDE":"Ein eingeschränkte:r (restricted) Nutzer:in darf sich lediglich anmelden und sein Passwort ändern. Der oder die Nutzer:in wird mit einem externen Usermanagementsystem synchronisiert.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, + {"i18nKey":"user.restricted","bundleName":"I18nResources","translation":"restricted","translationDE":"eingeschränkt","usedInClasses":["org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, + {"i18nKey":"user.restricted.not","bundleName":"I18nResources","translation":"not restricted","translationDE":"nicht eingeschränkt","usedInClasses":["org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, + {"i18nKey":"user.restrictedUser","bundleName":"I18nResources","translation":"Restricted user","translationDE":"Eingeschränkte:r Nutzer:in","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListForm"],"usedInFiles":[]}, + {"i18nKey":"user.restrictedUser.tooltip","bundleName":"I18nResources","translation":"A restricted user has only the ability to log-in and to change his password, but the user is synchronized with the external user management system.","translationDE":"Ein eingeschränkte:r (restricted) Nutzer:in darf sich lediglich anmelden und sein Passwort ändern. Der oder die Nutzer:in wird mit einem externen Usermanagementsystem synchronisiert.","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm"],"usedInFiles":[]}, {"i18nKey":"user.rights.title.edit","bundleName":"I18nResources","translation":"Edit user rights","translationDE":"Benutzer:innenrechte bearbeiten","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.sshPublicKey","bundleName":"I18nResources","translation":"SSH public key","translationDE":"SSH public key","usedInClasses":["org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, {"i18nKey":"user.title.add","bundleName":"I18nResources","translation":"Add new user","translationDE":"Neue:r Benutzer:in","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.title.edit","bundleName":"I18nResources","translation":"Edit user","translationDE":"Benutzer:in bearbeiten","usedInClasses":["org.projectforge.web.user.UserEditPage","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, {"i18nKey":"user.title.heading","bundleName":"I18nResources","translation":"Users","translationDE":"Benutzer:in","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.title.list","bundleName":"I18nResources","translation":"List of users","translationDE":"Benutzer:in","usedInClasses":["org.projectforge.web.user.UserEditPage","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, - {"i18nKey":"user.title.list.select","bundleName":"I18nResources","translation":"Select user","translationDE":"Benutzer:in auswählen","usedInClasses":["org.projectforge.web.user.UserEditPage","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, + {"i18nKey":"user.title.list.select","bundleName":"I18nResources","translation":"Select user","translationDE":"Benutzer:in auswählen","usedInClasses":["org.projectforge.web.user.UserEditPage","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, {"i18nKey":"user.unassignedGroups","bundleName":"I18nResources","translation":"Unassigned groups","translationDE":"Nicht assoziierte Gruppen","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"user.username","bundleName":"I18nResources","translation":"User name","translationDE":"Benutzer:inname","usedInClasses":["org.projectforge.business.fibu.EmployeeDao","org.projectforge.business.humanresources.HRPlanningDao","org.projectforge.business.timesheet.TimesheetDao","org.projectforge.business.user.UserPrefDao","org.projectforge.business.user.UserRightDao","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.rest.ChangePasswordPageRest","org.projectforge.rest.calendar.VacationServicesRest","org.projectforge.rest.fibu.EmployeePagesRest","org.projectforge.web.fibu.EmployeeSelectPanel","org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, {"i18nKey":"user.users","bundleName":"I18nResources","translation":"Users","translationDE":"Benutzer:in","usedInClasses":["org.projectforge.web.user.UserListPage"],"usedInFiles":[]}, {"i18nKey":"userPref.area","bundleName":"I18nResources","translation":"Area","translationDE":"Bereich","usedInClasses":["org.projectforge.web.user.UserPrefEditForm","org.projectforge.web.user.UserPrefListPage"],"usedInFiles":[]}, {"i18nKey":"userPref.area.jira.project","bundleName":"I18nResources","translation":"JIRA project","translationDE":"JIRA Projekt","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.area.jira.project.pid","bundleName":"I18nResources","translation":"Project id (pid)","translationDE":"Projekt ID (PID)","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"userPref.area.jira.project.pid.tooltip","bundleName":"I18nResources","translation":"You can get the project pid from JIRA dashboard from some links (url parameter called projectID or pid). It's needed for the communication with JIRA.","translationDE":"Kann im JIRA-Dashboard z. B. aus einigen Links abgelesen werden (projectID oder pid in der referenzierten URL). Wird für die Kommunikation mit JIRA benötigt.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"userPref.area.jira.project.pid.tooltip","bundleName":"I18nResources","translation":"You can get the project pid from JIRA dashboard from some links (url parameter called projectID or pid). It's needed for the communication with JIRA.","translationDE":"Kann im JIRA-Dashboard z. B. aus einigen Links abgelesen werden (projectID oder pid in der referenzierten URL). Wird für die Kommunikation mit JIRA benötigt.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.area.kunde.favorite","bundleName":"I18nResources","translation":"Customer favorite","translationDE":"Kundenfavorit","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.area.projekt.favorite","bundleName":"I18nResources","translation":"Project favorite","translationDE":"Projektfavorit","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.area.task.favorite","bundleName":"I18nResources","translation":"Structure element favorite","translationDE":"Strukturelementfavorit","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.area.timesheet.template","bundleName":"I18nResources","translation":"Templates for time sheets","translationDE":"Zeitberichtsvorlage","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.area.user.favorite","bundleName":"I18nResources","translation":"User favorite (unused)","translationDE":"Benutzerfavorit (unbenutzt)","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.error.nameDoesAlreadyExist","bundleName":"I18nResources","translation":"An entry with this name does already exist.","translationDE":"Es existiert bereits ein Eintrag unter diesem Namen.","usedInClasses":["org.projectforge.web.user.UserPrefEditForm"],"usedInFiles":[]}, - {"i18nKey":"userPref.error.userIsNotOwner","bundleName":"I18nResources","translation":"User is not owner of preference entry.","translationDE":"Benutzer:in ist nicht Eigner:in dieser persönlichen Einstellung.","usedInClasses":["org.projectforge.business.user.UserPrefDao"],"usedInFiles":[]}, + {"i18nKey":"userPref.error.userIsNotOwner","bundleName":"I18nResources","translation":"User is not owner of preference entry.","translationDE":"Benutzer:in ist nicht Eigner:in dieser persönlichen Einstellung.","usedInClasses":["org.projectforge.business.user.UserPrefDao"],"usedInFiles":[]}, {"i18nKey":"userPref.favorite.create","bundleName":"I18nResources","translation":"--- create ---","translationDE":"--- anlegen ---","usedInClasses":["org.projectforge.web.wicket.components.FavoritesChoicePanel"],"usedInFiles":[]}, {"i18nKey":"userPref.favorite.select","bundleName":"I18nResources","translation":"--- Favorites ---","translationDE":"--- Favoriten ---","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.name","bundleName":"I18nResources","translation":"Name","translationDE":"Name","usedInClasses":["org.projectforge.web.user.UserPrefEditForm","org.projectforge.web.user.UserPrefListPage"],"usedInFiles":[]}, {"i18nKey":"userPref.saveAsTemplate","bundleName":"I18nResources","translation":"Save as template","translationDE":"Als Vorlage speichern","usedInClasses":["org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, {"i18nKey":"userPref.template.create","bundleName":"I18nResources","translation":"--- create ---","translationDE":"--- anlegen ---","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"userPref.template.select","bundleName":"I18nResources","translation":"--- Templates ---","translationDE":"--- Vorlagen ---","usedInClasses":["org.projectforge.plugins.todo.ToDoEditForm","org.projectforge.web.timesheet.TimesheetEditForm"],"usedInFiles":[]}, - {"i18nKey":"userPref.title.add","bundleName":"I18nResources","translation":"New user preference","translationDE":"Neue persönliche Einstellung","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"userPref.title.edit","bundleName":"I18nResources","translation":"Edit user preference","translationDE":"Persönliche Einstellung bearbeiten","usedInClasses":["org.projectforge.web.user.UserPrefEditPage","org.projectforge.web.user.UserPrefListPage"],"usedInFiles":[]}, - {"i18nKey":"userPref.title.heading","bundleName":"I18nResources","translation":"User preferences","translationDE":"Persönliche Einstellungen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"userPref.title.list","bundleName":"I18nResources","translation":"List of user preferences","translationDE":"Liste der persönlichen Einstellungen","usedInClasses":["org.projectforge.web.user.UserPrefEditPage","org.projectforge.web.user.UserPrefListPage"],"usedInFiles":[]}, + {"i18nKey":"userPref.title.add","bundleName":"I18nResources","translation":"New user preference","translationDE":"Neue persönliche Einstellung","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"userPref.title.edit","bundleName":"I18nResources","translation":"Edit user preference","translationDE":"Persönliche Einstellung bearbeiten","usedInClasses":["org.projectforge.web.user.UserPrefEditPage","org.projectforge.web.user.UserPrefListPage"],"usedInFiles":[]}, + {"i18nKey":"userPref.title.heading","bundleName":"I18nResources","translation":"User preferences","translationDE":"Persönliche Einstellungen","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"userPref.title.list","bundleName":"I18nResources","translation":"List of user preferences","translationDE":"Liste der persönlichen Einstellungen","usedInClasses":["org.projectforge.web.user.UserPrefEditPage","org.projectforge.web.user.UserPrefListPage"],"usedInFiles":[]}, {"i18nKey":"username","bundleName":"I18nResources","translation":"User name","translationDE":"Benutzer:innenname","usedInClasses":["org.projectforge.business.book.BookDO","org.projectforge.business.fibu.EmployeeDO","org.projectforge.business.ldap.PFUserDOConverter","org.projectforge.business.user.UserAuthenticationsDao","org.projectforge.business.user.UserDao","org.projectforge.framework.ToStringUtil","org.projectforge.framework.persistence.database.HistoryMigrateService","org.projectforge.framework.persistence.user.entities.PFUserDO","org.projectforge.plugins.merlin.rest.MerlinExecutionPageRest","org.projectforge.rest.MenuRest","org.projectforge.rest.MyAccountPageRest","org.projectforge.rest.UserPagesRest","org.projectforge.rest.calendar.CalendarSubscriptionInfoPageRest","org.projectforge.rest.pub.LoginPageRest","org.projectforge.rest.pub.PasswordResetPageRest","org.projectforge.rest.pub.SetupPageRest","org.projectforge.ui.UIInput","org.projectforge.web.admin.SetupForm","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserListPage","org.projectforge.web.user.UserSelectPanel"],"usedInFiles":[]}, {"i18nKey":"vacation","bundleName":"I18nResources","translation":"Vacation","translationDE":"Urlaub","usedInClasses":["org.projectforge.business.vacation.service.VacationExcelExporter","org.projectforge.business.vacation.service.VacationSendMailService","org.projectforge.menu.builder.MenuItemDefId","org.projectforge.rest.TeamCalPagesRest","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationExportPageRest","org.projectforge.rest.VacationPagesRest","org.projectforge.rest.calendar.FullCalendarEvent","org.projectforge.rest.calendar.VacationProvider","org.projectforge.rest.pub.CalendarSubscriptionServiceRest"],"usedInFiles":[]}, {"i18nKey":"vacation.Days","bundleName":"I18nResources","translation":"Vacation days","translationDE":"Urlaubstage","usedInClasses":["org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, - {"i18nKey":"vacation.annualleave","bundleName":"I18nResources","translation":"Number of leave days for the year","translationDE":"Anzahl Urlaubstage für Kalenderjahr","usedInClasses":["org.projectforge.rest.VacationAccountPageRest","org.projectforge.web.fibu.MonthlyEmployeeReportPage"],"usedInFiles":[]}, - {"i18nKey":"vacation.availabledays","bundleName":"I18nResources","translation":"Available vacation days","translationDE":"Verfügbare Urlaubstage","usedInClasses":["org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, - {"i18nKey":"vacation.availablevacation","bundleName":"I18nResources","translation":"Available vacation","translationDE":"Noch verfügbarer Urlaub","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, + {"i18nKey":"vacation.annualleave","bundleName":"I18nResources","translation":"Number of leave days for the year","translationDE":"Anzahl Urlaubstage für Kalenderjahr","usedInClasses":["org.projectforge.rest.VacationAccountPageRest","org.projectforge.web.fibu.MonthlyEmployeeReportPage"],"usedInFiles":[]}, + {"i18nKey":"vacation.availabledays","bundleName":"I18nResources","translation":"Available vacation days","translationDE":"Verfügbare Urlaubstage","usedInClasses":["org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, + {"i18nKey":"vacation.availablevacation","bundleName":"I18nResources","translation":"Available vacation","translationDE":"Noch verfügbarer Urlaub","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.calendar","bundleName":"I18nResources","translation":"Calendar","translationDE":"Kalender","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.conflict.info","bundleName":"I18nResources","translation":"A conflict exists: At least at one day no substitute is available. Please choose other or further substitutes.","translationDE":"Es besteht ein Konflikt mit den Abwesenheiten der Vertreter:innen. An mindestens einem Tag steht kein:e Vertreter:in zur Verfügung. Bitte andere oder weitere Vertretungen auswählen.","usedInClasses":["org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, + {"i18nKey":"vacation.conflict.info","bundleName":"I18nResources","translation":"A conflict exists: At least at one day no substitute is available. Please choose other or further substitutes.","translationDE":"Es besteht ein Konflikt mit den Abwesenheiten der Vertreter:innen. An mindestens einem Tag steht kein:e Vertreter:in zur Verfügung. Bitte andere oder weitere Vertretungen auswählen.","usedInClasses":["org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, {"i18nKey":"vacation.conflicts","bundleName":"I18nResources","translation":"Conflicts","translationDE":"Konflikte","usedInClasses":["org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, {"i18nKey":"vacation.countPerDay","bundleName":"I18nResources","translation":"vacation hours per day","translationDE":"Urlaubsstunden pro Urlaubstag","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.employee","bundleName":"I18nResources","translation":"Employee","translationDE":"Mitarbeiter","usedInClasses":["org.projectforge.business.vacation.model.RemainingLeaveDO","org.projectforge.business.vacation.model.VacationDO","org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, @@ -2635,21 +2689,21 @@ {"i18nKey":"vacation.mail.action","bundleName":"I18nResources","translation":"The application for leave of {0} for the period {1} was {2} by {3}.","translationDE":"Der Urlaubseintrag von {0} am {1} wurde {2} durch {3}.","usedInClasses":[],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, {"i18nKey":"vacation.mail.action.short","bundleName":"I18nResources","translation":"Application for leave of {0} for {1} was {2}","translationDE":"Urlaubseintrag von {0} am {1} wurde {2}","usedInClasses":["org.projectforge.business.vacation.service.VacationSendMailService"],"usedInFiles":[]}, {"i18nKey":"vacation.mail.link","bundleName":"I18nResources","translation":"See application","translationDE":"Zum Urlaubseintrag","usedInClasses":[],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, - {"i18nKey":"vacation.mail.modType.delete","bundleName":"I18nResources","translation":"deleted","translationDE":"gelöscht","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.mail.modType.delete","bundleName":"I18nResources","translation":"deleted","translationDE":"gelöscht","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.mail.modType.insert","bundleName":"I18nResources","translation":"created","translationDE":"angelegt","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.mail.modType.undelete","bundleName":"I18nResources","translation":"undeleted","translationDE":"wiederhergestellt","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.mail.modType.update","bundleName":"I18nResources","translation":"modified","translationDE":"geändert","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.mail.modType.update","bundleName":"I18nResources","translation":"modified","translationDE":"geändert","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.mail.period","bundleName":"I18nResources","translation":"{0}-{1} ({2} days)","translationDE":"{0}-{1} ({2} Tage)","usedInClasses":["org.projectforge.business.vacation.service.VacationSendMailService"],"usedInFiles":[]}, - {"i18nKey":"vacation.mail.reason.hr","bundleName":"I18nResources","translation":"You received this application for leave of {0}, because it''s a special vacation which needs approvement by any hr staff member.","translationDE":"Du erhählst diesen Urlaubseintrag von {0}, weil es ein Spezialurlaub ist, der die Freigabe von HR benötigt.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.mail.reason.manager","bundleName":"I18nResources","translation":"You were chosen for checking this application. Please edit this application for leave in ProjectForge or contact {0}.","translationDE":"Du wurdest zur Abstimmung ausgewählt. Bitte bearbeite diesen Urlaubseintrag in ProjectForge bzw. nimm bitte Kontakt zu {0} auf.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.mail.reason.other","bundleName":"I18nResources","translation":"You received this application for leave of {0} for information.","translationDE":"Du erhählst diesen Urlaubseintrag von {0} zur Information.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.mail.reason.hr","bundleName":"I18nResources","translation":"You received this application for leave of {0}, because it''s a special vacation which needs approvement by any hr staff member.","translationDE":"Du erhählst diesen Urlaubseintrag von {0}, weil es ein Spezialurlaub ist, der die Freigabe von HR benötigt.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.mail.reason.manager","bundleName":"I18nResources","translation":"You were chosen for checking this application. Please edit this application for leave in ProjectForge or contact {0}.","translationDE":"Du wurdest zur Abstimmung ausgewählt. Bitte bearbeite diesen Urlaubseintrag in ProjectForge bzw. nimm bitte Kontakt zu {0} auf.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.mail.reason.other","bundleName":"I18nResources","translation":"You received this application for leave of {0} for information.","translationDE":"Du erhählst diesen Urlaubseintrag von {0} zur Information.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.mail.reason.own","bundleName":"I18nResources","translation":"This is your application for leave ({0}).","translationDE":"Es ist dein Urlaubseintrag.","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.mail.reason.replacement","bundleName":"I18nResources","translation":"You were chosen as substitute for this leave. If you can''t substitute your colleague, please contact {0}.","translationDE":"Du wurdest als Vertretung ausgewählt. Bitte bearbeite diesen Eintrag oder nimm Kontakt zu {0} auf.","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.mail.reason.replacement","bundleName":"I18nResources","translation":"You were chosen as substitute for this leave. If you can''t substitute your colleague, please contact {0}.","translationDE":"Du wurdest als Vertretung ausgewählt. Bitte bearbeite diesen Eintrag oder nimm Kontakt zu {0} auf.","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.manager","bundleName":"I18nResources","translation":"Manager","translationDE":"Abstimmung","usedInClasses":["org.projectforge.business.vacation.model.VacationDO","org.projectforge.business.vacation.model.VacationMode","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationPagesRest"],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, - {"i18nKey":"vacation.neededdays","bundleName":"I18nResources","translation":"Needed vacation days","translationDE":"Benötigte Urlaubstage","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.neededdays","bundleName":"I18nResources","translation":"Needed vacation days","translationDE":"Benötigte Urlaubstage","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.other","bundleName":"I18nResources","translation":"Other","translationDE":"Anderer","usedInClasses":["org.projectforge.business.vacation.model.VacationMode"],"usedInFiles":[]}, {"i18nKey":"vacation.own","bundleName":"I18nResources","translation":"Own","translationDE":"Eigner:in","usedInClasses":["org.projectforge.business.vacation.model.VacationMode"],"usedInFiles":[]}, - {"i18nKey":"vacation.plandannualleave","bundleName":"I18nResources","translation":"Number of planned leave days for the rest of the year","translationDE":"Anzahl geplanter Urlaubstage für restliches Kalenderjahr","usedInClasses":["org.projectforge.web.fibu.MonthlyEmployeeReportPage"],"usedInFiles":[]}, + {"i18nKey":"vacation.plandannualleave","bundleName":"I18nResources","translation":"Number of planned leave days for the rest of the year","translationDE":"Anzahl geplanter Urlaubstage für restliches Kalenderjahr","usedInClasses":["org.projectforge.web.fibu.MonthlyEmployeeReportPage"],"usedInFiles":[]}, {"i18nKey":"vacation.previousyearleave","bundleName":"I18nResources","translation":"Previous year leave","translationDE":"Resturlaub aus dem Vorjahr","usedInClasses":["org.projectforge.business.vacation.model.RemainingLeaveDO","org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.previousyearleaveunused","bundleName":"I18nResources","translation":"Unused previous year leave until {0}","translationDE":"Ungenutzer Resturlaub zum {0}","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.previousyearleaveused","bundleName":"I18nResources","translation":"Previous year leave used","translationDE":"Genutzter Resturlaub aus dem Vorjahr","usedInClasses":[],"usedInFiles":[]}, @@ -2658,9 +2712,9 @@ {"i18nKey":"vacation.remainingLeaveFromYearUnused","bundleName":"I18nResources","translation":"Unused remaining leave from {0}.","translationDE":"Ungenutzer Resturlaub aus dem Jahr {0}","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.replacement","bundleName":"I18nResources","translation":"Substitution","translationDE":"Vertretung","usedInClasses":["org.projectforge.business.vacation.model.VacationDO","org.projectforge.business.vacation.model.VacationMode","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationPagesRest","org.projectforge.rest.calendar.VacationProvider"],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, {"i18nKey":"vacation.replacement.others","bundleName":"I18nResources","translation":"Other substitutes","translationDE":"Weitere Vertretungen","usedInClasses":["org.projectforge.business.vacation.model.VacationDO","org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, - {"i18nKey":"vacation.setStartAndEndFirst","bundleName":"I18nResources","translation":"","translationDE":"","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.setStartAndEndFirst","bundleName":"I18nResources","translation":"","translationDE":"","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.special","bundleName":"I18nResources","translation":"Special leave","translationDE":"Sonderurlaub","usedInClasses":["org.projectforge.business.vacation.model.VacationDO","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationPagesRest"],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, - {"i18nKey":"vacation.special.tooltip","bundleName":"I18nResources","translation":"Special leave days will be excluded from the vacation account.","translationDE":"Sonderurlaub wird im Urlaubskonto nicht berücksichtigt.","usedInClasses":["org.projectforge.business.vacation.model.VacationDO"],"usedInFiles":[]}, + {"i18nKey":"vacation.special.tooltip","bundleName":"I18nResources","translation":"Special leave days will be excluded from the vacation account.","translationDE":"Sonderurlaub wird im Urlaubskonto nicht berücksichtigt.","usedInClasses":["org.projectforge.business.vacation.model.VacationDO"],"usedInFiles":[]}, {"i18nKey":"vacation.specialApproved","bundleName":"I18nResources","translation":"Special leave approved","translationDE":"Abgestimmter Sonderurlaub","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.specialInProgress","bundleName":"I18nResources","translation":"Special leave in progress","translationDE":"Sonderurlaub in Abstimmung","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.specialVacationInYearApproved","bundleName":"I18nResources","translation":"Approved special leave in {0}","translationDE":"Abgestimmter Sonderurlaub in {0}","usedInClasses":[],"usedInFiles":[]}, @@ -2671,12 +2725,12 @@ {"i18nKey":"vacation.status.approved","bundleName":"I18nResources","translation":"Approved","translationDE":"Abgestimmt","usedInClasses":["org.projectforge.business.vacation.model.VacationStatus","org.projectforge.business.vacation.service.VacationExcelExporter"],"usedInFiles":[]}, {"i18nKey":"vacation.status.inProgress","bundleName":"I18nResources","translation":"In progress","translationDE":"In Abstimmung","usedInClasses":["org.projectforge.business.vacation.model.VacationStatus","org.projectforge.business.vacation.service.VacationExcelExporter"],"usedInFiles":[]}, {"i18nKey":"vacation.status.rejected","bundleName":"I18nResources","translation":"Rejected","translationDE":"Abgelehnt","usedInClasses":["org.projectforge.business.vacation.model.VacationStatus"],"usedInFiles":[]}, - {"i18nKey":"vacation.subscription","bundleName":"I18nResources","translation":"Subscription of employee leave days","translationDE":"Abonnieren von Urlaubseinträgen","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, - {"i18nKey":"vacation.subscription.info","bundleName":"I18nResources","translation":"Leave days are displayed on demand in the calendar view. They also may be defined as calendars (see list of calendars) for users and/or groups. These calendars can be subscribed for usage in 3rd party calendar tools.","translationDE":"Urlaubseinträge können in der Kalendersicht eingesehen werden, aber auch als Kalender (s. Kalenderliste) für bestimmte Benutzer:innen oder Gruppen angelegt und auch abonniert werden. Sie können insbesondere die eigenen Urlaube und die von Kollegen oder Kolleginnen/Teams in die eigene Kalendersoftware integriert werden.","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, + {"i18nKey":"vacation.subscription","bundleName":"I18nResources","translation":"Subscription of employee leave days","translationDE":"Abonnieren von Urlaubseinträgen","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, + {"i18nKey":"vacation.subscription.info","bundleName":"I18nResources","translation":"Leave days are displayed on demand in the calendar view. They also may be defined as calendars (see list of calendars) for users and/or groups. These calendars can be subscribed for usage in 3rd party calendar tools.","translationDE":"Urlaubseinträge können in der Kalendersicht eingesehen werden, aber auch als Kalender (s. Kalenderliste) für bestimmte Benutzer:innen oder Gruppen angelegt und auch abonniert werden. Sie können insbesondere die eigenen Urlaube und die von Kollegen oder Kolleginnen/Teams in die eigene Kalendersoftware integriert werden.","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.subtotal","bundleName":"I18nResources","translation":"Subtotal","translationDE":"Zwischensumme","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.title.add","bundleName":"I18nResources","translation":"Create leave application","translationDE":"Urlaubseintrag erstellen","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.title.edit","bundleName":"I18nResources","translation":"Edit leave application","translationDE":"Urlaubseintrag ändern","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.title.heading","bundleName":"I18nResources","translation":"Leave_Applications","translationDE":"Urlaubseinträge","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.title.edit","bundleName":"I18nResources","translation":"Edit leave application","translationDE":"Urlaubseintrag ändern","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.title.heading","bundleName":"I18nResources","translation":"Leave_Applications","translationDE":"Urlaubseinträge","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.title.list","bundleName":"I18nResources","translation":"Leave application list","translationDE":"Urlaubseintragsliste","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, {"i18nKey":"vacation.usedvacation","bundleName":"I18nResources","translation":"Used vacation","translationDE":"Bereits verwendeter Urlaub","usedInClasses":[],"usedInFiles":[]}, {"i18nKey":"vacation.vacationApproved","bundleName":"I18nResources","translation":"Approved Vacation","translationDE":"Abgestimmter Urlaub","usedInClasses":["org.projectforge.rest.VacationAccountPageRest"],"usedInFiles":[]}, @@ -2685,16 +2739,16 @@ {"i18nKey":"vacation.vacationer","bundleName":"I18nResources","translation":"Vacationer","translationDE":"Urlauber","usedInClasses":[],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, {"i18nKey":"vacation.vacationmode","bundleName":"I18nResources","translation":"Assignment","translationDE":"Zuordnung","usedInClasses":["org.projectforge.business.vacation.model.VacationDO","org.projectforge.rest.VacationAccountPageRest","org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, {"i18nKey":"vacation.vacationsOfReplacements","bundleName":"I18nResources","translation":"Vacations of substitutes","translationDE":"Urlaube der Vertretungen","usedInClasses":["org.projectforge.rest.VacationPagesRest"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.datenotset","bundleName":"I18nResources","translation":"Start- and end-date are required.","translationDE":"Das Start- und das Enddatum müssen angegeben sein.","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.datenotset","bundleName":"I18nResources","translation":"Start- and end-date are required.","translationDE":"Das Start- und das Enddatum müssen angegeben sein.","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, {"i18nKey":"vacation.validate.daysarenull","bundleName":"I18nResources","translation":"vacation with 0 workdays","translationDE":"Urlaubseintrag mit 0 Arbeitstagen","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.endbeforestart","bundleName":"I18nResources","translation":"The choosen end date is before start date","translationDE":"Das gewählte Enddatum liegt vor dem Startdatum","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.leaveapplicationexists","bundleName":"I18nResources","translation":"A leave application already exists for this period","translationDE":"Für den ausgewählten Zeitraum existiert bereits ein Urlaubseintrag","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.noCalender","bundleName":"I18nResources","translation":"The company vacation calendar {0} must be selected","translationDE":"Der Firmenurlaubskalender {0} muss ausgewählt werden","usedInClasses":[],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.notAllowedToSelfApprove","bundleName":"I18nResources","translation":"You're not allowed to approve this entry.","translationDE":"Sie können diesen Eintrag nicht als abgestimmt markieren.","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.notEnoughVacationDaysLeft","bundleName":"I18nResources","translation":"There are not enough free vacation days left","translationDE":"Es stehen nicht mehr genügend Urlaubstage zur Verfügung","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.startDateBeforeNow","bundleName":"I18nResources","translation":"The chosen start date is before now. Only HR employees can create data before now.","translationDE":"Das gewählte Startdatum liegt vor dem aktuellen Datum. Nur HR-Mitarbeiter:innen können Daten in der Vergangenheit anlegen.","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.usedBiggerThanPreviousYear","bundleName":"I18nResources","translation":"Count of used vacation days is bigger than count of days which are taken from last year vacation.","translationDE":"Die Anzahl der verbrauchten Tage aus dem Urlaub vom Vorjahr ist größer als die tatsächliche Anzahl der Urlaubstage aus dem Vorjahr.","usedInClasses":["org.projectforge.web.fibu.EmployeeVacationFormValidator"],"usedInFiles":[]}, - {"i18nKey":"vacation.validate.usedButNoPreviousYear","bundleName":"I18nResources","translation":"You only have used days for previous year entered but not how many days there was taken from previous year.","translationDE":"Es wurden nur die verbrauchten Tage des Urlaubs aus dem Vorjahr angegeben, aber nicht die tatsächlichen.","usedInClasses":["org.projectforge.web.fibu.EmployeeVacationFormValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.endbeforestart","bundleName":"I18nResources","translation":"The choosen end date is before start date","translationDE":"Das gewählte Enddatum liegt vor dem Startdatum","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.leaveapplicationexists","bundleName":"I18nResources","translation":"A leave application already exists for this period","translationDE":"Für den ausgewählten Zeitraum existiert bereits ein Urlaubseintrag","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.noCalender","bundleName":"I18nResources","translation":"The company vacation calendar {0} must be selected","translationDE":"Der Firmenurlaubskalender {0} muss ausgewählt werden","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.notAllowedToSelfApprove","bundleName":"I18nResources","translation":"You're not allowed to approve this entry.","translationDE":"Sie können diesen Eintrag nicht als abgestimmt markieren.","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.notEnoughVacationDaysLeft","bundleName":"I18nResources","translation":"There are not enough free vacation days left","translationDE":"Es stehen nicht mehr genügend Urlaubstage zur Verfügung","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.startDateBeforeNow","bundleName":"I18nResources","translation":"The chosen start date is before now. Only HR employees can create data before now.","translationDE":"Das gewählte Startdatum liegt vor dem aktuellen Datum. Nur HR-Mitarbeiter:innen können Daten in der Vergangenheit anlegen.","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.usedBiggerThanPreviousYear","bundleName":"I18nResources","translation":"Count of used vacation days is bigger than count of days which are taken from last year vacation.","translationDE":"Die Anzahl der verbrauchten Tage aus dem Urlaub vom Vorjahr ist größer als die tatsächliche Anzahl der Urlaubstage aus dem Vorjahr.","usedInClasses":["org.projectforge.web.fibu.EmployeeVacationFormValidator"],"usedInFiles":[]}, + {"i18nKey":"vacation.validate.usedButNoPreviousYear","bundleName":"I18nResources","translation":"You only have used days for previous year entered but not how many days there was taken from previous year.","translationDE":"Es wurden nur die verbrauchten Tage des Urlaubs aus dem Vorjahr angegeben, aber nicht die tatsächlichen.","usedInClasses":["org.projectforge.web.fibu.EmployeeVacationFormValidator"],"usedInFiles":[]}, {"i18nKey":"vacation.validate.vacationBeforeJoinDate","bundleName":"I18nResources","translation":"Vacations before joining of an employee are not allowed.","translationDE":"Der Urlaub darf nicht vor dem Eintrittsdatum des Mitarbeiters liegen.","usedInClasses":["org.projectforge.business.vacation.service.VacationValidator"],"usedInFiles":[]}, {"i18nKey":"vacation.workingdays","bundleName":"I18nResources","translation":"Workdays","translationDE":"Anzahl Urlaubstage","usedInClasses":["org.projectforge.rest.VacationPagesRest"],"usedInFiles":["./projectforge-business/src/main/resources/mail/vacationMail.html"]}, {"i18nKey":"validation.error.fieldRequired","bundleName":"I18nResources","translation":"Field ''{0}'' is required.","translationDE":"Feld ''{0}'' muss ausgefüllt werden.","usedInClasses":["org.projectforge.framework.i18n.RequiredFieldIsEmptyException","org.projectforge.plugins.merlin.MerlinVariable","org.projectforge.rest.AddressPagesRest","org.projectforge.rest.core.AbstractPagesRest","org.projectforge.ui.ValidationError","org.projectforge.web.wicket.AbstractForm","org.projectforge.web.wicket.WebConstants"],"usedInFiles":[]}, @@ -2708,14 +2762,14 @@ {"i18nKey":"value","bundleName":"I18nResources","translation":"Value","translationDE":"Wert","usedInClasses":["org.projectforge.business.fibu.kost.BusinessAssessmentRowConfig","org.projectforge.business.user.UserRightVO","org.projectforge.flyway.dbmigration.V7_0_0_11__MigrateEmployeeAnnualLeaveDays","org.projectforge.flyway.dbmigration.V7_0_0_6__MigrateEmployeeAndCarryVacationDays","org.projectforge.framework.persistence.history.HistoryFormatUserAdapter","org.projectforge.framework.persistence.user.entities.UserPrefEntryDO","org.projectforge.framework.persistence.user.entities.UserRightDO","org.projectforge.framework.utils.KeyValueBean","org.projectforge.framework.utils.LabelValueBean","org.projectforge.plugins.marketing.AddressCampaignValueDO","org.projectforge.plugins.marketing.AddressCampaignValueDao","org.projectforge.plugins.marketing.AddressCampaignValueEditForm","org.projectforge.plugins.marketing.AddressCampaignValueExport","org.projectforge.plugins.marketing.AddressCampaignValueListForm","org.projectforge.plugins.marketing.AddressCampaignValueListPage","org.projectforge.plugins.marketing.rest.AddressCampaignValueMultiSelectedPageRest","org.projectforge.plugins.marketing.rest.AddressCampaignValuePagesRest","org.projectforge.rest.core.RestResolver","org.projectforge.rest.dvelop.DvelopClient","org.projectforge.ui.UISelect","org.projectforge.web.admin.ConfigurationListPage","org.projectforge.web.core.importstorage.AbstractImportStoragePanel","org.projectforge.web.teamcal.event.MyWicketEvent","org.projectforge.web.user.UserEditForm","org.projectforge.web.user.UserPrefEditForm"],"usedInFiles":["./projectforge-business/src/main/resources/mail/orderChangeNotification.html","./projectforge-business/src/main/resources/mail/todoChangeNotification.html","./projectforge-business/src/main/resources/mail/vacationMail.html","./projectforge-wicket/src/main/java/org/projectforge/web/core/importstorage/AbstractImportStoragePanel.html"]}, {"i18nKey":"values","bundleName":"I18nResources","translation":"Values","translationDE":"Werte","usedInClasses":["org.projectforge.business.ldap.LdapGroupValues","org.projectforge.business.ldap.LdapUserValues","org.projectforge.plugins.marketing.AddressCampaignDO","org.projectforge.plugins.marketing.AddressCampaignEditForm","org.projectforge.plugins.marketing.AddressCampaignListPage","org.projectforge.plugins.marketing.rest.AddressCampaignPagesRest","org.projectforge.rest.json.UISelectTypeSerializer"],"usedInFiles":[]}, {"i18nKey":"webauthn.entry.displayName","bundleName":"I18nResources","translation":"Display name","translationDE":"Anzeigename","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.security.webauthn.WebAuthnEntryDO"],"usedInFiles":[]}, - {"i18nKey":"webauthn.entry.displayName.info","bundleName":"I18nResources","translation":"Feel free to enter any name to identify your WebAuthn token.","translationDE":"Hier kannst du einen beliebigen Namen eingeben, um deinen Token leichter zuordnen zu können.","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest"],"usedInFiles":[]}, - {"i18nKey":"webauthn.entry.edit","bundleName":"I18nResources","translation":"Edit WebAuthn entry","translationDE":"WebAuthn-Eintrag ändern","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest"],"usedInFiles":[]}, - {"i18nKey":"webauthn.entry.signCount","bundleName":"I18nResources","translation":"Sign count","translationDE":"Signaturzähler","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.security.webauthn.WebAuthnEntryDO"],"usedInFiles":[]}, - {"i18nKey":"webauthn.entry.signCount.info","bundleName":"I18nResources","translation":"Counter of authentications (will be incremented on every token usage)","translationDE":"Zähler für Authentifizierungen (wird nach jeder Benutzung hochgezählt)","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.security.webauthn.WebAuthnEntryDO"],"usedInFiles":[]}, + {"i18nKey":"webauthn.entry.displayName.info","bundleName":"I18nResources","translation":"Feel free to enter any name to identify your WebAuthn token.","translationDE":"Hier kannst du einen beliebigen Namen eingeben, um deinen Token leichter zuordnen zu können.","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest"],"usedInFiles":[]}, + {"i18nKey":"webauthn.entry.edit","bundleName":"I18nResources","translation":"Edit WebAuthn entry","translationDE":"WebAuthn-Eintrag ändern","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest"],"usedInFiles":[]}, + {"i18nKey":"webauthn.entry.signCount","bundleName":"I18nResources","translation":"Sign count","translationDE":"Signaturzähler","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.security.webauthn.WebAuthnEntryDO"],"usedInFiles":[]}, + {"i18nKey":"webauthn.entry.signCount.info","bundleName":"I18nResources","translation":"Counter of authentications (will be incremented on every token usage)","translationDE":"Zähler für Authentifizierungen (wird nach jeder Benutzung hochgezählt)","usedInClasses":["org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.security.webauthn.WebAuthnEntryDO"],"usedInFiles":[]}, {"i18nKey":"webauthn.error.process","bundleName":"I18nResources","translation":"Error while processing authentication.","translationDE":"Fehler im Authentifizierungsprozess.","usedInClasses":["org.projectforge.security.webauthn.WebAuthnSupport"],"usedInFiles":[]}, - {"i18nKey":"webauthn.error.userNotOwnerOrEntryDoesnotExist","bundleName":"I18nResources","translation":"The user has no access to this foreign webauthn entry or no such entry exists.","translationDE":"Der/die Benutzer:in hat nicht das Recht, auf fremde WebAuthn-Einträge zuzugreifen oder der gesuchte Eintrag existiert nicht.","usedInClasses":["org.projectforge.security.webauthn.WebAuthnEntryDao"],"usedInFiles":[]}, + {"i18nKey":"webauthn.error.userNotOwnerOrEntryDoesnotExist","bundleName":"I18nResources","translation":"The user has no access to this foreign webauthn entry or no such entry exists.","translationDE":"Der/die Benutzer:in hat nicht das Recht, auf fremde WebAuthn-Einträge zuzugreifen oder der gesuchte Eintrag existiert nicht.","usedInClasses":["org.projectforge.security.webauthn.WebAuthnEntryDao"],"usedInFiles":[]}, {"i18nKey":"webauthn.error.validate","bundleName":"I18nResources","translation":"Error while validating authentication.","translationDE":"Fehler bei der Validierung der Authentifizierungsdaten.","usedInClasses":["org.projectforge.security.webauthn.WebAuthnSupport"],"usedInFiles":[]}, - {"i18nKey":"webauthn.info","bundleName":"I18nResources","translation":"WebAuthn is a modern and secure standard for having secure 2FA hardware tokens. You may here register your hardware tokens.","translationDE":"WebAuthn ist ein moderner und sicherer Standard, um eine hardwarebasierte Zweifaktorauthentifizierung zu ermöglichen. Hier kannst du einen oder mehrere deiner Token registrieren, um eine bequeme und sichere 2FA zu nutzen.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, + {"i18nKey":"webauthn.info","bundleName":"I18nResources","translation":"WebAuthn is a modern and secure standard for having secure 2FA hardware tokens. You may here register your hardware tokens.","translationDE":"WebAuthn ist ein moderner und sicherer Standard, um eine hardwarebasierte Zweifaktorauthentifizierung zu ermöglichen. Hier kannst du einen oder mehrere deiner Token registrieren, um eine bequeme und sichere 2FA zu nutzen.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"webauthn.registration.2FARequired.info","bundleName":"I18nResources","translation":"Please renew Your 2FA before registering Your WebAuthn token.","translationDE":"Bitte de 2FA erneuern, bevor ein WebAuthn-Token registriert werden kann.","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"webauthn.registration.button.authenticate","bundleName":"I18nResources","translation":"WebAuthn","translationDE":"WebAuthn","usedInClasses":["org.projectforge.security.WebAuthnServicesRest"],"usedInFiles":[]}, {"i18nKey":"webauthn.registration.button.authenticate.info","bundleName":"I18nResources","translation":"You may use any of your registered WebAuthn tokens here (for example Yubikey).","translationDE":"Du kannst hier registrierte WebAuthn-Token benutzen (z. B. Yubikey).","usedInClasses":["org.projectforge.security.WebAuthnServicesRest"],"usedInFiles":[]}, @@ -2723,7 +2777,7 @@ {"i18nKey":"webauthn.title","bundleName":"I18nResources","translation":"WebAuthn (Fido2 etc.)","translationDE":"WebAuthn (Fido2 etc.)","usedInClasses":["org.projectforge.rest.my2fa.My2FASetupPageRest"],"usedInFiles":[]}, {"i18nKey":"weekOfYear","bundleName":"I18nResources","translation":"Week of year","translationDE":"Kalenderwoche","usedInClasses":["org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.calendar.CalendarSubscriptionInfoPageRest","org.projectforge.rest.pub.CalendarSubscriptionServiceRest"],"usedInFiles":[]}, {"i18nKey":"wizard","bundleName":"I18nResources","translation":"Wizard","translationDE":"Assistent","usedInClasses":["org.projectforge.rest.task.TaskWizardPageRest","org.projectforge.web.admin.TaskWizardForm","org.projectforge.web.task.TaskTreePage"],"usedInFiles":[]}, - {"i18nKey":"yes","bundleName":"I18nResources","translation":"Yes","translationDE":"Ja","usedInClasses":["org.projectforge.business.vacation.service.VacationSendMailService","org.projectforge.framework.xmlstream.XmlHelper","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.TokenInfoPageRest","org.projectforge.rest.dto.Vacation","org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.ui.LayoutUtils","org.projectforge.ui.UIAttachmentList","org.projectforge.ui.UIButton","org.projectforge.web.dialog.ModalQuestionDialog"],"usedInFiles":["./projectforge-business/src/main/kotlin/org/projectforge/framework/i18n/I18n.kt"]}, + {"i18nKey":"yes","bundleName":"I18nResources","translation":"Yes","translationDE":"Ja","usedInClasses":["org.projectforge.business.vacation.service.VacationSendMailService","org.projectforge.framework.xmlstream.XmlHelper","org.projectforge.rest.TimesheetPagesRest","org.projectforge.rest.TokenInfoPageRest","org.projectforge.rest.dto.Vacation","org.projectforge.rest.my2fa.WebAuthnEntryPageRest","org.projectforge.rest.poll.PollPageRest","org.projectforge.ui.LayoutUtils","org.projectforge.ui.UIAttachmentList","org.projectforge.ui.UIButton","org.projectforge.web.dialog.ModalQuestionDialog"],"usedInFiles":["./projectforge-business/src/main/kotlin/org/projectforge/framework/i18n/I18n.kt"]}, {"i18nKey":"plugins.licensemanagement.device","bundleName":"LicenseManagementI18nResources","translation":"Device","translationDE":"Gerät","usedInClasses":["org.projectforge.plugins.licensemanagement.LicenseDO","org.projectforge.plugins.licensemanagement.LicenseEditForm","org.projectforge.plugins.licensemanagement.LicenseListPage"],"usedInFiles":[]}, {"i18nKey":"plugins.licensemanagement.device.tooltip","bundleName":"LicenseManagementI18nResources","translation":"On which device(s) is this software installed?","translationDE":"Auf welchem/welchen Gerät(en) ist die Software installiert?","usedInClasses":["org.projectforge.plugins.licensemanagement.LicenseEditForm"],"usedInFiles":[]}, {"i18nKey":"plugins.licensemanagement.file1","bundleName":"LicenseManagementI18nResources","translation":"File 1","translationDE":"Datei 1","usedInClasses":["org.projectforge.plugins.licensemanagement.LicenseEditForm"],"usedInFiles":[]}, @@ -3013,6 +3067,14 @@ {"i18nKey":"plugins.teamcal.title.list.select","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.web.teamcal.admin.TeamCalEditPage","org.projectforge.web.teamcal.admin.TeamCalListPage"],"usedInFiles":[]}, {"i18nKey":"plugins.teamcalendar.event","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.user.UserRightId"],"usedInFiles":[]}, {"i18nKey":"plugins.todo.title.list.select","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.plugins.todo.ToDoEditPage","org.projectforge.plugins.todo.ToDoListPage"],"usedInFiles":[]}, + {"i18nKey":"poll.attendee_groups","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.poll.PollDO"],"usedInFiles":[]}, + {"i18nKey":"poll.error.closed","bundleName":null,"translation":null,"translationDE":"Umfrage wurde bereits beendet","usedInClasses":[],"usedInFiles":[]}, + {"i18nKey":"poll.full_access_groups","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.poll.PollDO"],"usedInFiles":[]}, + {"i18nKey":"poll.full_access_user","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.poll.PollDO"],"usedInFiles":[]}, + {"i18nKey":"poll.inputFields","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.poll.PollDO"],"usedInFiles":[]}, + {"i18nKey":"poll.response.owner","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.poll.PollResponseDO"],"usedInFiles":[]}, + {"i18nKey":"poll.response.poll","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.poll.PollResponseDO"],"usedInFiles":[]}, + {"i18nKey":"poll.responses","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.business.poll.PollResponseDO"],"usedInFiles":[]}, {"i18nKey":"timesheet.title.list.select","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.web.timesheet.TimesheetEditPage","org.projectforge.web.timesheet.TimesheetListPage"],"usedInFiles":[]}, {"i18nKey":"userPref.title.list.select","bundleName":null,"translation":null,"translationDE":null,"usedInClasses":["org.projectforge.web.user.UserPrefEditPage","org.projectforge.web.user.UserPrefListPage"],"usedInFiles":[]} ] diff --git a/projectforge-business/src/main/java/org/projectforge/framework/persistence/api/BaseDao.java b/projectforge-business/src/main/java/org/projectforge/framework/persistence/api/BaseDao.java index caeb8548ec..8078e349ea 100644 --- a/projectforge-business/src/main/java/org/projectforge/framework/persistence/api/BaseDao.java +++ b/projectforge-business/src/main/java/org/projectforge/framework/persistence/api/BaseDao.java @@ -1115,7 +1115,6 @@ public boolean hasInsertAccess(final PFUserDO user) { public boolean hasLoggedInUserUpdateAccess(final O obj, final O dbObj, final boolean throwException) { return hasUpdateAccess(ThreadLocalUserContext.getUser(), obj, dbObj, throwException); } - /** * Checks update access right by calling hasAccess(obj, OperationType.UPDATE). * diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollDO.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollDO.kt new file mode 100644 index 0000000000..76f4e412c6 --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollDO.kt @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll + +import org.hibernate.search.annotations.Indexed +import org.projectforge.business.poll.filter.PollAssignment +import org.projectforge.business.poll.filter.PollState +import org.projectforge.common.StringHelper +import org.projectforge.common.anots.PropertyInfo +import org.projectforge.framework.persistence.api.AUserRightId +import org.projectforge.framework.persistence.entities.DefaultBaseDO +import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext +import org.projectforge.framework.persistence.user.entities.PFUserDO +import org.springframework.context.annotation.DependsOn +import java.time.LocalDate +import javax.persistence.* + + +@Entity +@Indexed +@Table(name = "t_poll") +@AUserRightId(value = "poll", checkAccess = false) +@DependsOn("org.projectforge.framework.persistence.user.entities.PFUserDO") +open class PollDO : DefaultBaseDO() { + + @PropertyInfo(i18nKey = "poll.title") + @get:Column(name = "title", nullable = false, length = 1000) + open var title: String? = null + + @PropertyInfo(i18nKey = "poll.description") + @get:Column(name = "description", length = 10000) + open var description: String? = null + + @get:PropertyInfo(i18nKey = "poll.owner") + @get:ManyToOne(fetch = FetchType.LAZY) + @get:JoinColumn(name = "owner_fk", nullable = false) + open var owner: PFUserDO? = null + + @PropertyInfo(i18nKey = "poll.location") + @get:Column(name = "location") + open var location: String? = null + + @PropertyInfo(i18nKey = "poll.deadline") + @get:Column(name = "deadline", nullable = false) + open var deadline: LocalDate? = null + + + @PropertyInfo(i18nKey = "poll.attendees") + @get:Column(name = "attendeeIds", nullable = true) + open var attendeeIds: String? = null + + @PropertyInfo(i18nKey = "poll.attendee_groups") + @get:Column(name = "groupAttendeeIds", nullable = true) + open var groupAttendeeIds: String? = null + + @PropertyInfo(i18nKey = "poll.full_access_groups") + @get:Column(name = "full_access_group_ids", length = 4000, nullable = true) + open var fullAccessGroupIds: String? = null + + @PropertyInfo(i18nKey = "poll.full_access_user") + @get:Column(name = "full_access_user_ids", length = 4000, nullable = true) + open var fullAccessUserIds: String? = null + + @PropertyInfo(i18nKey = "poll.inputFields") + @get:Column(name = "inputFields", length = 1000) + open var inputFields: String? = null + + @PropertyInfo(i18nKey = "poll.state") + @get:Column(name = "state", nullable = false) + open var state: State = State.RUNNING + + @Transient + fun getPollAssignment(): MutableList { + val currentUserId = ThreadLocalUserContext.userId!! + val assignmentList = mutableListOf() + if (currentUserId == this.owner?.id) { + assignmentList.add(PollAssignment.OWNER) + } + val accessUserIds = toIntArray(this.fullAccessUserIds) + if (accessUserIds?.contains(currentUserId) == true) { + assignmentList.add(PollAssignment.ACCESS) + } + val attendeeUserIds = toIntArray(this.attendeeIds) + if (attendeeUserIds?.contains(currentUserId) == true) { + assignmentList.add(PollAssignment.ATTENDEE) + } + if (assignmentList.isEmpty()) + assignmentList.add(PollAssignment.OTHER) + + return assignmentList + } + + @Transient + fun getPollStatus(): PollState { + return if (this.state == State.FINISHED) { + PollState.FINISHED + } else if (this.state == State.RUNNING) { + PollState.RUNNING + } else { + PollState.FINISHED_AND_MAIL_SENT + } + } + + enum class State { + RUNNING, FINISHED, FINISHED_AND_MAIL_SENT + } + + companion object { + fun toIntArray(str: String?): IntArray? { + if (str.isNullOrBlank()) return null + return StringHelper.splitToInts(str, ",", false) + } + } +} diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollDao.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollDao.kt new file mode 100644 index 0000000000..611b59ed1f --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollDao.kt @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll + +import org.projectforge.business.group.service.GroupService +import org.projectforge.framework.access.OperationType +import org.projectforge.framework.persistence.api.BaseDao +import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext +import org.projectforge.framework.persistence.user.entities.PFUserDO +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Repository + +@Repository +open class PollDao : BaseDao(PollDO::class.java) { + + @Autowired + private lateinit var groupService: GroupService + + override fun newInstance(): PollDO { + return PollDO() + } + + override fun hasAccess( + user: PFUserDO?, + obj: PollDO?, + oldObj: PollDO?, + operationType: OperationType?, + throwException: Boolean + ): Boolean { + + if (obj == null && operationType == OperationType.SELECT) { + return true + }; + if (obj != null && operationType == OperationType.SELECT) { + if (hasFullAccess(obj) || isAttendee(obj, ThreadLocalUserContext.user?.id!!)) + return true + } + if (obj != null) { + return hasFullAccess(obj) + } + return false + } + + // returns true if current user has full access, otherwise returns false + fun hasFullAccess(obj: PollDO): Boolean { + val loggedInUserId = ThreadLocalUserContext.userId!! + if (!obj.fullAccessUserIds.isNullOrBlank()) { + val userIdArray = PollDO.toIntArray(obj.fullAccessUserIds) + if (userIdArray?.contains(loggedInUserId) == true) { + return true + } + } + if (obj.owner?.id == loggedInUserId) { + return true + } + if (!obj.fullAccessGroupIds.isNullOrBlank()) { + val groupIdArray = PollDO.toIntArray(obj.fullAccessGroupIds) + val groupUsers = groupService.getGroupUsers(groupIdArray) + groupUsers.map { it.id }.forEach { id -> + if (id == loggedInUserId) { + return true + } + } + } + return false + } + + fun isAttendee(obj: PollDO, user: Int): Boolean { + return PollDO.toIntArray(obj.attendeeIds)?.contains(user) == true + } +} \ No newline at end of file diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollResponseDO.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollResponseDO.kt new file mode 100644 index 0000000000..23f105a7a0 --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollResponseDO.kt @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll + +import org.hibernate.search.annotations.Indexed +import org.projectforge.common.anots.PropertyInfo +import org.projectforge.framework.persistence.api.AUserRightId +import org.projectforge.framework.persistence.entities.DefaultBaseDO +import org.projectforge.framework.persistence.user.entities.PFUserDO +import org.springframework.context.annotation.DependsOn +import javax.persistence.* + +@Entity +@Indexed +@Table(name = "t_poll_response") +@AUserRightId(value = "poll.response", checkAccess = false) +@DependsOn("org.projectforge.framework.persistence.user.entities.PFUserDO") +open class PollResponseDO : DefaultBaseDO() { + + @get:PropertyInfo(i18nKey = "poll.response.poll") + @get:ManyToOne(fetch = FetchType.LAZY) + @get:JoinColumn(name = "poll_fk", nullable = false) + open var poll: PollDO? = null + + @get:PropertyInfo(i18nKey = "poll.response.owner") + @get:ManyToOne(fetch = FetchType.LAZY) + @get:JoinColumn(name = "owner_fk", nullable = false) + open var owner: PFUserDO? = null + + @PropertyInfo(i18nKey = "poll.responses") + @get:Column(name = "responses", nullable = true, length = 1000) + open var responses: String? = null +} diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollResponseDao.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollResponseDao.kt new file mode 100644 index 0000000000..3fb7cb0170 --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/PollResponseDao.kt @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll + +import org.projectforge.framework.access.OperationType +import org.projectforge.framework.persistence.api.BaseDao +import org.projectforge.framework.persistence.user.entities.PFUserDO +import org.springframework.stereotype.Repository + +@Repository +open class PollResponseDao : BaseDao(PollResponseDO::class.java) { + override fun newInstance(): PollResponseDO { + return PollResponseDO() + } + + override fun hasAccess( + user: PFUserDO?, + obj: PollResponseDO?, + oldObj: PollResponseDO?, + operationType: OperationType?, + throwException: Boolean + ): Boolean { + return true + } +} diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollAssignment.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollAssignment.kt new file mode 100644 index 0000000000..23691b54dd --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollAssignment.kt @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll.filter + +import org.projectforge.common.i18n.I18nEnum + +enum class PollAssignment(val key: String) : I18nEnum { + OWNER("owner"), ACCESS("access"), ATTENDEE("attendee"), OTHER("other"); + + override val i18nKey: String + get() = ("poll.$key") +} diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollAssignmentFilter.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollAssignmentFilter.kt new file mode 100644 index 0000000000..bc20b61c7b --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollAssignmentFilter.kt @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll.filter + +import org.projectforge.business.group.service.GroupService +import org.projectforge.business.poll.PollDO +import org.projectforge.framework.configuration.ApplicationContextProvider +import org.projectforge.framework.persistence.api.impl.CustomResultFilter +import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext +import org.projectforge.framework.persistence.user.entities.PFUserDO + +class PollAssignmentFilter(val values: List) : CustomResultFilter { + + override fun match(list: MutableList, element: PollDO): Boolean { + var foundUser: PFUserDO? = null + if (!element.fullAccessGroupIds.isNullOrEmpty()) { + val groupIds = element.fullAccessGroupIds!!.split(", ").map { it.toInt() }.toIntArray() + val accessUsers = groupService.getGroupUsers(groupIds) + val localUser = ThreadLocalUserContext.userId!! + foundUser = accessUsers.firstOrNull { user -> user.id == localUser } + } + + values.forEach { filter -> + if (element.getPollAssignment() + .contains(filter) || (filter == PollAssignment.ACCESS && foundUser != null) + ) { + return true + } + } + return false + } + + companion object { + private var _groupService: GroupService? = null + private val groupService: GroupService + get() { + if (_groupService == null) { + _groupService = ApplicationContextProvider.getApplicationContext().getBean(GroupService::class.java) + } + return _groupService!! + } + } +} diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollState.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollState.kt new file mode 100644 index 0000000000..220e660070 --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollState.kt @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll.filter + +import org.projectforge.common.i18n.I18nEnum + +enum class PollState(val key: String) : I18nEnum { + RUNNING("running"), FINISHED("finished"), FINISHED_AND_MAIL_SENT("finished and mail sent"); + + override val i18nKey: String + get() = "poll.$key" +} diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollStateFilter.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollStateFilter.kt new file mode 100644 index 0000000000..6446987a1f --- /dev/null +++ b/projectforge-business/src/main/kotlin/org/projectforge/business/poll/filter/PollStateFilter.kt @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.business.poll.filter; + +import org.projectforge.business.poll.PollDO +import org.projectforge.framework.persistence.api.impl.CustomResultFilter + +class PollStateFilter(val values: List) : CustomResultFilter { + + override fun match(list: MutableList, element: PollDO): Boolean { + return values.contains(element.getPollStatus()) + } +} diff --git a/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuCreator.kt b/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuCreator.kt index c1e7f9e103..9bcc916e1d 100644 --- a/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuCreator.kt +++ b/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuCreator.kt @@ -455,6 +455,7 @@ open class MenuCreator { requiredUserRightId = ContractDao.USER_RIGHT_ID, requiredUserRightValues = READONLY_READWRITE ) ) + //.add(MenuItemDef(MenuItemDefId.POLL)) .add( MenuItemDef( MenuItemDefId.VISITORBOOK, diff --git a/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuItemDefId.kt b/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuItemDefId.kt index 4823000601..931304104f 100644 --- a/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuItemDefId.kt +++ b/projectforge-business/src/main/kotlin/org/projectforge/menu/builder/MenuItemDefId.kt @@ -87,6 +87,7 @@ enum class MenuItemDefId constructor(val i18nKey: String, val url: String? = nul OUTGOING_INVOICE_LIST("menu.fibu.rechnungen", "wa/outgoingInvoiceList"), // PERSONAL_STATISTICS("menu.personalStatistics", "wa/personalStatistics"), // PHONE_CALL("menu.phoneCall", "wa/phoneCall"), // + POLL("menu.poll", getReactListUrl("poll")), // PROJECT_LIST("menu.fibu.projekte", getReactListUrl("project")), // REPORT_OBJECTIVES("menu.fibu.reporting.reportObjectives", "wa/reportObjectives"), // SEND_SMS("menu.sendSms", "wa/sendSms"), // diff --git a/projectforge-business/src/main/resources/I18nResources.properties b/projectforge-business/src/main/resources/I18nResources.properties index 538e83e647..8b5157e6aa 100644 --- a/projectforge-business/src/main/resources/I18nResources.properties +++ b/projectforge-business/src/main/resources/I18nResources.properties @@ -13,19 +13,15 @@ validation.error.range.integerOutOfRange=Value out of range {0}-{1}. validation.error.range.integerToHigh=Value must not be higher than {0}. validation.error.range.integerToLow=Value must not be lower than {0}. validation.required.valueNotPresent=Value ''{0}'' not present. - # React UI select.placeholder=Select... table.showing=Showing - # own validations: bicvalidator.wronglength=The field ''${label}'' must be 8 or 11 characters long. ibanvalidator.wronglength.de=The field ''${label}'' starts with ''DE'', but a german IBAN must have 22 characters. - # Currency format currencyConverter.percentage.help=You can enter amounts as well as percent values (e. g. 10%). currencyFormat={0,number,,##0.00} - # Not internationalized properties: exception.notYetSupported=Not yet supported. menu.adminGuide=Administration guide @@ -35,7 +31,6 @@ menu.projectDocumentation=Project docs menu.sqlConsole=SQL console menu.userGuide=Handbuch message.notYetImplemented=Not yet implemented. - # Buttons: add=Add assign=Assign @@ -98,191 +93,7 @@ updateAndNext=Update and next upload=Upload uptodate=up-to-date wizard=Wizard - # Common -akquise=Acquisition -changes=Changes -charactersLeft=characters left. -color.error.unknownFormat=Color code in unsupported format. Supported hex formats: #abc or #abcdef -comment=Comment -completed=completed -contactPerson=Contact person -created=created -createdBy=created by -date=date -date.begin=Start date -date.end=End date -date.from=from -date.until=until -dateFormat=Date format -dateFormat.xls=Excel date format -day=day(s) -days=days -deadline=Deadline -default=Default -deleted=deleted -description=Description -dueDate=Due date -edit=Edit -email=E-mail -ended=ended -error=An error occurs: {0} -errors=Errors -export=Export -fieldNotHistorizable=Field not historizable. -file=file -file.upload.audit.action.delete=deleted -file.upload.audit.action.download=downloaded -file.upload.audit.action.downloadAll=downloaded all -file.upload.audit.action.downloadMulti=downloaded multi -file.upload.audit.action.modification=modified (name or description) -file.upload.audit.action.upload=uploaded -file.upload.choose=Choose file -file.upload.deleteSelected=Delete selected -file.upload.deleteSelected.confirm=Do you really want to delete all selected files? -file.upload.downloadSelected=Download selected -file.upload.dropArea=Select a file, or drop it here. -file.upload.error.fileAlreadyExists=File ''{0}'' already exists. -file.upload.error.maxSizeExceeded=Can''t upload file ''{0}'', maximum configured file size is exceeded: {1}>{2}. -file.upload.error.maxSizeOfExceeded=File upload rejected: maximum size of {0} exceeded. -file.upload.error.noFileSelected=No file selected -file.upload.error.toManyFiles=You tried to upload to many files at once. -filing=filing -filter=filter -filter.all=all -filter.extendedSearch=Extended search -filter.faulty=faulty -filter.newest=newest -financeAdministration=Finance administration -firstName=First name -gender=Gender -gender.diverse=diverse -gender.female=female -gender.male=male -gender.notApplicable=not applicable -gender.notKnown=not known -gender.unknown=unknown -group=Group -holidays=Holidays -hours=Hours -id=Id -imageFile=Image -inherit=inherit -key=Key -language=Language -lastUpdate=last modification -legend=Legend -list=List -listView=List view -loading=Loading... -loggedInUserInfo=Current user: -longFormat=Long format -misc=Miscellaneous -modifications=Modifications -modificationTime=Time of modification -modified=modified -modifiedBy=modified by -modifiedHistoryValue=history value of modification -moreEntriesAvailable=More entries available. -name=Name -new=New -nickname=Nickname -no=No -notEnded=not ended -nothingFound=Nothing found. -notLoggedIn=Not logged in. -notVisible=not visible -oclock=o'clock -onlyDeleted=only deleted -onlyDeleted.tooltip=Only deleted entries will be displayed (in general independent of any other filter settings). -operation.deleted=deleted -operation.inserted=inserted -operation.markAsDeleted=marked as deleted -operation.undefined=undefined -operation.undeleted=undeleted -operation.updated=updated -organization=Organization -password=Password -passwordRepeat=Repeat password -percent=Percent -pleaseChoose=Please choose -printView=print view -priority=Priority -priority.high=high -priority.highest=highest -priority.least=least -priority.low=low -priority.middle=middle -priority.without=without -quickselect=Quick-select -recursive=recursive -rest=Rest -resubmissionOnDate=Resubmission on -resumption=Resumption -searchFilter=Search filter -searchString=Search string -securityAdvice=Security advice -settings=Settings -shortDescription=Short description -sql=SQL -statistics=Statistics -status=Status -sum=Sum -task=Structure element -templates=Templates -templates.new=New template -text=Text -timeago.afewseconds=a few seconds ago -timeago.days={0} days ago -timeago.days.one=yesterday -timeago.hours={0} hours ago -timeago.hours.one=an hour ago -timeago.minutes={0} minutes ago -timeago.minutes.one=a minute ago -timeago.months={0} months ago -timeago.months.one=a month ago -timeago.negative=in the future! -timeago.seconds={0} seconds ago -timeago.weeks={0} weeks ago -timeago.weeks.one=a week ago -timeago.years={0} years ago -timeago.years.one=a year ago -timeleft.afewseconds=in a few seconds -timeleft.days=in {0} days -timeleft.days.one=tomorrow -timeleft.hours=in {0} hours -timeleft.hours.one=in an hour -timeleft.minutes=in {0} minutes -timeleft.minutes.one=in a minute -timeleft.months=in {0} months -timeleft.months.one=in a month -timeleft.negative=in the past! -timeleft.seconds=in {0} seconds -timeleft.weeks=in {0} weeks -timeleft.weeks.one=in a week -timeleft.years=in {0} years -timeleft.years.one=in a year -timeNotation=Time notation -timeNotation.12=12-hour notation -timeNotation.24=24-hour notation -timeOfCreation=Time of creation -timeOfLastUpdate=Time of last update -timePeriod=Time period -timestamp=Time stamp -timezone=Time zone -tip=Tip -title=Title -totalSum=Total sum -undefined=undefined -until=until -untitled=untitled -user=User -username=User name -value=Value -values=Values -weekOfYear=Week of year -yes=Yes - access=Accessright access.accessTable=Access table access.exception.demoUserHasNoAccess=The demo user is blocked for this action. @@ -584,6 +395,7 @@ administration.setup.target.testdata.tooltip=Database with test data (for test s administration.setup.title=First login - set-up ProjectForge administration.title=Administration agGrid.sortInfo=You may sort multiple columns by pressing shift-key while clicking column heads. You may also re-order columns and change the width of the columns. +akquise=Acquisition attachment=Attachment attachment.checksum=Checksum attachment.encrypt=Encrypt @@ -780,6 +592,10 @@ calendar.view.workDays=Workdays calendar.week=week calendar.weekOfYearShortLabel=CW calendar.year=Year +changes=Changes +charactersLeft=characters left. +color.error.unknownFormat=Color code in unsupported format. Supported hex formats: #abc or #abcdef +comment=Comment common.attention=Attention! common.customized=Customized common.import.action.commit=Commit @@ -824,6 +640,7 @@ common.resultholder.ok=ok common.resultholder.warning=warning common.uploadpanel.filetolarge=Selected file is too large. The maximal size is {0}. common.uploadpanel.filewrongtype=Selected file is in incorrect format. Supported formats: {0} +completed=completed contact.birthday=Birthday contact.contacts=Addresses contact.emailValues=Email addresses @@ -842,13 +659,30 @@ contact.type.other=other contact.type.own=own contact.type.postal=postal contact.type.private=private +contactPerson=Contact person contextMenu.cancel=Cancel contextMenu.newTab=Open in new tab +created=created +createdBy=created by +date=date +date.begin=Start date +date.end=End date +date.from=from +date.until=until +dateFormat=Date format +dateFormat.xls=Excel date format +day=day(s) +days=days +deadline=Deadline +default=Default +deleted=deleted +description=Description dialog.title.error=An error occured! dialog.title.information=Information dialog.title.message=Message dialog.title.success=Success message dialog.title.warning=Warning +dueDate=Due date duration.days={0} days duration.days.one=1 day duration.hours={0} hours @@ -858,6 +692,10 @@ duration.minutes.one=1 minute duration.seconds={0} seconds duration.seconds.one=1 second dvelop.title=D-velop +edit=Edit +email=E-mail +ended=ended +error=An error occurs: {0} error.date.yearOutOfRange=The year of the date is out of range: ${minimumYear} - ${maximumYear}. error.dateInFuture=Date is in future. error.endDateBeforeBeginDate=End date can't be before begin date. @@ -872,12 +710,14 @@ errorpage.feedback.messageNumber=Message number errorpage.feedback.placeholder=Please decripe how you get the failure. errorpage.title=An error has been occurred. errorpage.unknownError=An internal error has been occurred. +errors=Errors exception.constraintViolation=A constraint violation occured. The current data object results in a conflict with another existing (perhaps deleted) object in the data base. exception.flowscope.notExists=Flow scope does not exist (maybe caused by a timeout). Please try again. exception.internalError=An internal error occured. A log message was produced. exception.luceneParseError=Error while parsing string: {0}. exception.pleaseContactDeveloperTeam=Internal error, please contact the developer team (the message id in error log: #{0}). exception.scriptError=Exception while script execution thrown: {0} +export=Export feedback.link.tooltip=Send feed-back feedback.mailSendSuccessful=E-Mail was sent successful. Thank you for your feed-back! feedback.receiver=Receiver @@ -1296,8 +1136,32 @@ fibu.tooltip.unselectKost1=Unselect Kost1 fibu.tooltip.unselectKost2=Unselect Kost2 fibu.tooltip.unselectKunde=Unselect customer fibu.tooltip.unselectProjekt=Unselect project +fieldNotHistorizable=Field not historizable. +file=file file.panel.deleteExistingFile.heading=Deletion of the file? file.panel.deleteExistingFile.question=Do you really want to delete or overwrite the existing file? +file.upload.audit.action.delete=deleted +file.upload.audit.action.download=downloaded +file.upload.audit.action.downloadAll=downloaded all +file.upload.audit.action.downloadMulti=downloaded multi +file.upload.audit.action.modification=modified (name or description) +file.upload.audit.action.upload=uploaded +file.upload.choose=Choose file +file.upload.deleteSelected=Delete selected +file.upload.deleteSelected.confirm=Do you really want to delete all selected files? +file.upload.downloadSelected=Download selected +file.upload.dropArea=Select a file, or drop it here. +file.upload.error.fileAlreadyExists=File ''{0}'' already exists. +file.upload.error.maxSizeExceeded=Can''t upload file ''{0}'', maximum configured file size is exceeded: {1}>{2}. +file.upload.error.maxSizeOfExceeded=File upload rejected: maximum size of {0} exceeded. +file.upload.error.noFileSelected=No file selected +file.upload.error.toManyFiles=You tried to upload to many files at once. +filing=filing +filter=filter +filter.all=all +filter.extendedSearch=Extended search +filter.faulty=faulty +filter.newest=newest finance.accountingRecord.dc=DC finance.accountingRecord.dc.credit=credit finance.accountingRecord.dc.debit=debit @@ -1305,6 +1169,8 @@ finance.datev.import.error.titleRowMissed=Title row missed. finance.datev.upload.hint=*.xls; max. {0} finance.datev.uploadAccountingRecords=upload accounting records finance.datev.uploadAccountList=upload accounts +financeAdministration=Finance administration +firstName=First name form.ajaxEditableLabel.tooltip=Click for edit mode. gantt.access.all=All gantt.access.owner=Owner @@ -1373,6 +1239,14 @@ gantt.x.unit.day=day gantt.x.unit.month=month gantt.x.unit.quarter=quarter gantt.x.unit.week=week +gender=Gender +gender.diverse=diverse +gender.female=female +gender.male=male +gender.notApplicable=not applicable +gender.notKnown=not known +gender.unknown=unknown +group=Group group.assignedUsers=Assigned users group.error.groupnameAlreadyExists=Group name already exists. group.groups=Groups @@ -1399,6 +1273,8 @@ history.newValue=New value history.oldValue=Old value history.propertyName=Property history.was=was +holidays=Holidays +hours=Hours hr.planning.description=Activity report hr.planning.entry.copyFromPredecessor=Copy from predecessor hr.planning.entry.error.entryDoesAlreadyExistForUserAndWeekOfYear=An entry with the same user and week of year does already exist. @@ -1434,6 +1310,8 @@ hr.planning.unassignedHours=without assigned day hr.planning.view.title=Human resources view hr.planning.weekend=Week-end hr.planning.workdays=Workdays +id=Id +imageFile=Image import.confirmMessage=Would you like to import the selected entries now? This option isn't undoable. import.display.options=Display options import.entry.error=Error @@ -1468,6 +1346,7 @@ import.title=Import tool index.development=Website for developers index.website=Website index.welcome=Welcome to ProjectForge. +inherit=inherit jira.chooseProject=--- Choose JIRA project --- jobs.error.refusedByAnotherRunningJob=Job couldn't be started: Another job is already running in this queue. jobs.error.waitingTimeExceeded=Job couldn't be started due to a time-out: This job is blocked by other long-running job(s). @@ -1486,6 +1365,7 @@ jobs.job.terminatedAt=Terminated at jobs.job.title=Job title jobs.monitor.noJobsAvailable=No current jobs jobs.monitor.title=Job monitor +key=Key label.data=Data label.exportFormat=Export format label.filterSettings=Filter settings @@ -1503,6 +1383,8 @@ label.script=Script label.script.result=Script result label.sendEMailNotification=Send an e-mail notification? label.sendShortMessage=Send the assignee a text message? +language=Language +lastUpdate=last modification ldap=LDAP ldap.gidNumber=GID number ldap.gidNumber.alreadyInUse=GID number is already assigned to another group. The next free GID number is {0}. @@ -1553,7 +1435,11 @@ legalAffaires.contract.type=Type legalAffaires.contract.validity=Validity legalAffaires.contract.validity.from=Validity from legalAffaires.contract.validity.until=Validity until +legend=Legend license.upload.title=License file +list=List +listView=List view +loading=Loading... locale.de=German locale.en=English locale.zh=Chinese @@ -1562,6 +1448,7 @@ log.level.error=Error log.level.info=Info log.level.trace=Trace log.level.warn=Warn +loggedInUserInfo=Current user: login.adminLoginRequired=Maintenance mode: Please use ProjectForge only as administrator! login.error.loginExpired=Login failed. Please contact an administrator because your log-in is expired. login.error.loginFailed=Login failed. Please check your login name and password (case sensitive!). @@ -1578,6 +1465,7 @@ login.successful=You're sucessfully logged in. Enjoy ProjectForge! login.timeOffset=Your account is now locked for further {0} seconds due to {1} failed login attempts. Please try again later. login.title=Login logout.successful=Logout was successful. +longFormat=Long format mail.error.exception=An error occured during while sending e-mail. A log message was produced. Please contact a system administrator. mail.error.missingToAddress=Sending of e-mail failed, no receiver address is given. mail.template.closing=Enjoy your work with ProjectForge! @@ -1687,6 +1575,7 @@ menu.personalStatistics=My statistics menu.phoneCall=Direct call menu.pluginAdmin=Plugins menu.plugins.teamcal=List of calendars +menu.poll=Polls menu.projectmanagement=Project management menu.reindexAllDatabaseEntries=Re-build whole search index menu.reindexAllDatabaseEntries.tooltip.content=The whole index will be rebuilt. This may take a while (serveral minute for e. g. 100.000 entries) and the system performance is affected. Therefore this feature is only enabled for administrators. @@ -1716,11 +1605,35 @@ message.successfullChanged=Successfull changed. message.successfullCompleted=Successfull completed: {0} message.title=Message message.wicket.pageExpired=The demanded page is expired. +misc=Miscellaneous +modifications=Modifications +modificationTime=Time of modification +modified=modified +modifiedBy=modified by +modifiedHistoryValue=history value of modification +moreEntriesAvailable=More entries available. multiselection.aggrid.selection.info.message=\ * You may use the shift-key for multi-selection on mouse clicks.\n\ * You may use cursor up- and down keys to navigate and use space to (de)select rows. multiselection.aggrid.selection.info.title=Multi selection of rows multiselection.button=Multi selection +name=Name +new=New +nickname=Nickname +no=No +notEnded=not ended +nothingFound=Nothing found. +notLoggedIn=Not logged in. +notVisible=not visible +oclock=o'clock +onlyDeleted=only deleted +onlyDeleted.tooltip=Only deleted entries will be displayed (in general independent of any other filter settings). +operation.deleted=deleted +operation.inserted=inserted +operation.markAsDeleted=marked as deleted +operation.undefined=undefined +operation.undeleted=undeleted +operation.updated=updated orga.post.inhalt=Content orga.post.type=Type orga.post.type.brief=Letter @@ -1763,10 +1676,12 @@ orga.visitorbook.visitortype.family=Family orga.visitorbook.visitortype.normal=Normal orga.visitorbook.visitortype.supplier=Supplier orga.visitorbook.visitortype.workman=Workman +organization=Organization pacman.title=Pacman panel.error.customernameNotFound=Customer name doesn't exist. panel.error.groupNotFound=Group doesn't exist. panel.error.projectNotFound=Project doesn't exist. +password=Password password.forgotten.link=Forgotten credentials? password.forgotten.mail.subject=Password reset ProjectForge® password.forgotten.mailSentTo=Mail with reset link mailed to ''{0}''. Please check also Your spam folder and check, if Your username or e-mail is correct. @@ -1778,10 +1693,13 @@ password.reset.mail.message.1=Please note: You will need a second authentificati password.reset.mail.message.2=If you haven't configured a second factor, such as Authenticator-App or mobile phone, You have to contact Your ProjectForge administrator. password.reset.title=Reset password password.reset.username_email=Username/e-mail +passwordRepeat=Repeat password +percent=Percent personal.statistics.timesheetDisciplineChart.title=Early booking of time sheets is essentiell for a successful project management! personal.statistics.timesheetDisciplineChart1.legend=The last {0} days results in {1} workhours. For this period {2} hours where already booked. personal.statistics.timesheetDisciplineChart2.legend=In the last {0} days time sheets were booked after {2} days (average). The goal is to achieve {1} days at maximum. personal.statistics.title=My Statistics +pleaseChoose=Please choose plugins.teamcal.access=Access right plugins.teamcal.access.groups=Groups plugins.teamcal.access.title=Access options @@ -1974,6 +1892,164 @@ plugins.teamcal.title.add=Add calendar plugins.teamcal.title.edit=Edit team calendar plugins.teamcal.title.heading=Calendar plugins.teamcal.title.list=List of calendars +printView=print view +priority=Priority +priority.high=high +priority.highest=highest +priority.least=least +priority.low=low +priority.middle=middle +priority.without=without +quickselect=Quick-select +recursive=recursive +rest=Rest +resubmissionOnDate=Resubmission on +resumption=Resumption +searchFilter=Search filter +searchString=Search string +securityAdvice=Security advice +settings=Settings +shortDescription=Short description +sql=SQL +statistics=Statistics +status=Status +sum=Sum +task=Structure element +templates=Templates +templates.new=New template +text=Text +timeago.afewseconds=a few seconds ago +timeago.days={0} days ago +timeago.days.one=yesterday +timeago.hours={0} hours ago +timeago.hours.one=an hour ago +timeago.minutes={0} minutes ago +timeago.minutes.one=a minute ago +timeago.months={0} months ago +timeago.months.one=a month ago +timeago.negative=in the future! +timeago.seconds={0} seconds ago +timeago.weeks={0} weeks ago +timeago.weeks.one=a week ago +timeago.years={0} years ago +timeago.years.one=a year ago +timeleft.afewseconds=in a few seconds +timeleft.days=in {0} days +timeleft.days.one=tomorrow +timeleft.hours=in {0} hours +timeleft.hours.one=in an hour +timeleft.minutes=in {0} minutes +timeleft.minutes.one=in a minute +timeleft.months=in {0} months +timeleft.months.one=in a month +timeleft.negative=in the past! +timeleft.seconds=in {0} seconds +timeleft.weeks=in {0} weeks +timeleft.weeks.one=in a week +timeleft.years=in {0} years +timeleft.years.one=in a year +timeNotation=Time notation +timeNotation.12=12-hour notation +timeNotation.24=24-hour notation +timeOfCreation=Time of creation +timeOfLastUpdate=Time of last update +timePeriod=Time period +timestamp=Time stamp +timezone=Time zone +tip=Tip +title=Title +totalSum=Total sum +undefined=undefined +until=until +untitled=untitled +user=User +username=User name +value=Value +values=Values +weekOfYear=Week of year +yes=Yes +# poll plugin +poll=Poll +poll.access=Access +poll.answer=Answer +poll.assignment=Assignment +poll.attendee=Attendee +poll.attendees=Attendees +poll.button.addQuestion=Add own question +poll.button.finish=Finish Poll +poll.button.template=Use Template +poll.confirmation.creation=Do you really want to create the poll? You won't be able to edit the questions afterwards.\ +Also make sure to add attendees for your poll. +poll.confirmation.deleteAnswer=Do you really want to delete this answer? +poll.confirmation.deleteQuestion=Do you really want to delete this question? +poll.confirmation.finish=Do you really want to finish this Poll? +poll.date=Date +poll.deadline=Deadline +poll.delegationAnswers=Answers of +poll.description=Description +poll.error.oneQuestionRequired=At least one question is required. +poll.exception.noAttendee=This user is not part of the poll. +poll.export.response.poll=Export results +poll.finished=Finished +poll.fullAccessGroups=Full Access Groups +poll.fullAccessUsers=Full Access User +poll.groupAttendees=Attendee Groups +poll.guide=Poll Guide +poll.infopage=Info Page +poll.location=Location +poll.mail.ended.content=

Dear Attendees,

\ +

We wanted to let you know that the poll "{0}" created by {1} has now ended. Thank you to everyone who participated and provided valuable input.

\ +

If you missed the deadline to submit your responses, we encourage you to still share your thoughts with us. While we may not be able to include your responses in the official results, your feedback is still valuable for future polls.

\ +

Thank you again for your participation.

\ +

Best regards,

\ +

{1}

+poll.mail.ended.subject=Poll ended +poll.mail.endingSoon.content=

Dear Attendees,

\ +

This is a friendly reminder that the poll "{0}" created by {1} is ending soon, on {2}. Please make sure to submit your responses before the deadline.

\ +

If you have not yet had a chance to participate, please take a few moments to do so before the poll closes. Your input is important and valued.

\ +

{3}

\ +

Thank you for your attention, and have a great day!

\ +

Best regards,

\ +

{1}

+poll.mail.endingSoon.subject=Poll ending in {0} days +poll.mail.update.content=

Dear Attendees,

\ +

We wanted to let you know that the poll "{0}" was edited recently.

\ +

If you already submitted your answers, you should check, if there were any major changes made.

\ +

Thank you again for your participation.

\ +

Best regards,

\ +

{1}

+poll.mail.update.subject=Poll was edited +poll.other=Other +poll.owner=Owner +poll.popup.closed=The poll was already closed. +poll.question=Question +poll.question.textQuestion=Text Question +poll.questionType=Question Type +poll.respond=Send responses +poll.response.mail.update.content=

Dear {0},

\ +

I wanted to inform you that Person {2} has updated their answer to Poll {1}.

\ +

If you were not notified about this,

\ +

I recommend reaching out to the person directly or adjusting your results accordingly.

\ +

You can modify your response until "{3}".

\ +

Best regards,

\ +

{2}

+poll.response.mail.update.subject=Response was edited by {0} +poll.response.page=Poll Response Page +poll.response.title=Poll Response Page +poll.running=Running +poll.selectUser=Select user +poll.state=State +poll.title=Title +poll.title.add=Create new Poll +poll.title.edit=Edit Poll +poll.title.list=Polls +poll.userDelegation=User delegation +poll.yourAnswers=Your answers +poll.manual.title=Guide to Creating a Poll | First, you need to fill in the main information of the poll. +poll.manual.questions=Next, create the questions for the poll. The questions can be of various types. +poll.manual.singleResponse=A question where you can choose one answer. For example, for a simple Yes or No question. +poll.manual.multiResponse=A question where you can choose multiple answers. Well-suited for a date availability survey. +poll.manual.textQuestion=A question where you can answer with free text. Great for informal feedback. projectmanagement.personDays=Person days projectmanagement.personDays.short=pd question.deleteQuestion=Do your really want to delete this object finally? @@ -1985,7 +2061,7 @@ scripting.download.filename.additional=Download only available for a few minutes scripting.download.filename.info=File generated by last script run. scripting.myScript.list=My scripts scripting.script=Script -scripting.script.availableVariables=Availabe variables +scripting.script.availableVariables=Available variables scripting.script.description.tooltip=Markdown format is supported. scripting.script.downloadBackups=Download backups scripting.script.downloadEffectiveScript=Download effective script @@ -2578,7 +2654,6 @@ webauthn.registration.button.authenticate=WebAuthn webauthn.registration.button.authenticate.info=You may use any of your registered WebAuthn tokens here (for example Yubikey). webauthn.registration.button.register=Register webauthn.title=WebAuthn (Fido2 etc.) - # (timeable) attributes attr.deletemodal.heading=Would you like to delete this entry? attr.deletemodal.question=Yes: This entry will be deleted and all changes on this page will be saved.
Cancel: This entry will not be deleted and you stay on this page. diff --git a/projectforge-business/src/main/resources/I18nResources_de.properties b/projectforge-business/src/main/resources/I18nResources_de.properties index 8a9d8fa52e..6164577113 100644 --- a/projectforge-business/src/main/resources/I18nResources_de.properties +++ b/projectforge-business/src/main/resources/I18nResources_de.properties @@ -5,7 +5,6 @@ # This main function sorts all entries in default properties and ensures the same output in this lang properties. # # Any comment or blank line of this file will be ignored and replaced by such lines from default properties. - # ******** Entries in 'I18nResources_de.properties' MISSED in default 'I18nResources.properties': # birthdayTool.email.content=Anbei die Liste der Geburtstage für den nächsten Monat.
Diese E-Mail wurde automatisch von ProjectForge generiert. @@ -16,7 +15,7 @@ birthdayTool.month.response.nothingSelected=Der Monat muss ausgewählt sein. birthdayTool.organization.noMatchingUser=Es gibt keine Benutzer:innen, die der gesetzten Organisation zugeordnet sind. birthdayTool.organization.notSet=Es ist keine Organisation in den application.properties definiert. -> projectforge.birthdayTool.organization=Your Organization birthdayTool.wordDocument.error=Es ist ein Fehler beim Erstellen des Word-Dokuments aufgetreten. - +poll.error.closed=Umfrage wurde bereits beendet # Missed translations from default 'I18nResources.properties' (might be OK): # # exception.notYetSupported=Not yet supported. @@ -48,6 +47,8 @@ birthdayTool.wordDocument.error=Es ist ein Fehler beim Erstellen des Word-Dokume # menu.luceneConsole=Lucene Console # menu.multiTenancy=Multi tenancy # menu.pluginAdmin=Plugins +# poll.response.mail.update.content=

Dear {0},

... (multiline) +# poll.response.mail.update.subject=Response was edited by {0} # sipgate.title=Sipgate # system.admin.alertMessage.copyAndPaste.title=For copy & paste # system.admin.button.checkI18nProperties=Check i18n properties @@ -116,19 +117,15 @@ validation.error.range.integerOutOfRange=Wert außerhalb des Bereichs {0} - {1}. validation.error.range.integerToHigh=Wert darf nicht größer als {0} sein. validation.error.range.integerToLow=Wert darf nicht kleiner als {0} sein. validation.required.valueNotPresent=Wert ''{0}'' nicht gegeben. - # React UI select.placeholder=Auswählen... table.showing=Anzeige - # own validations: bicvalidator.wronglength=Das Feld ''${label}'' muss 8 oder 11 Zeichen lang sein. ibanvalidator.wronglength.de=Das Feld ''${label}'' beginnt mit ''DE''. Eine deutsche IBAN muss jedoch aus 22 Zeichen bestehen. - # Currency format currencyConverter.percentage.help=Es können sowohl Beträge als auch Prozentzahlen (z. B. 10%) eingegeben werden. currencyFormat={0,number,,##0.00} - # Not internationalized properties: ### not translated: exception.notYetSupported=Not yet supported. ### not translated: menu.adminGuide=Administration guide @@ -138,7 +135,6 @@ currencyFormat={0,number,,##0.00} ### not translated: menu.sqlConsole=SQL console ### not translated: menu.userGuide=Handbuch ### not translated: message.notYetImplemented=Not yet implemented. - # Buttons: add=Hinzufügen assign=Zuweisen @@ -201,191 +197,7 @@ updateAndNext=Ändern und nächster upload=Hochladen uptodate=aktuell wizard=Assistent - # Common -akquise=Akquise -changes=Änderungen -charactersLeft=Zeichen übrig. -color.error.unknownFormat=Farbcode kann nicht verarbeitet werden. Unterstützte Hex-Farbformate: #abc or #abcdef -comment=Bemerkung -completed=erledigt -contactPerson=Ansprechpartner:in -created=angelegt -createdBy=angelegt von -date=Datum -date.begin=Beginndatum -date.end=Endedatum -date.from=von -date.until=bis -dateFormat=Datumsformat -dateFormat.xls=Exceldatumsformat -day=Tag(e) -days=Tage -deadline=Frist -default=Standard -deleted=gelöscht -description=Beschreibung -dueDate=Fälligkeit -edit=Bearbeiten -email=E-Mail -ended=beendet -error=Ein Fehler trat auf: {0} -errors=Fehler -export=Export -fieldNotHistorizable=Dieses Feld wird nicht historisiert! -file=Datei -file.upload.audit.action.delete=gelöscht -file.upload.audit.action.download=heruntergeladen -file.upload.audit.action.downloadAll=alles heruntergeladen -file.upload.audit.action.downloadMulti=mehrere heruntergeladen -file.upload.audit.action.modification=geändert (Dateiname oder Beschreibung) -file.upload.audit.action.upload=hochgeladen -file.upload.choose=Datei wählen -file.upload.deleteSelected=Ausgewählte Dateien löschen -file.upload.deleteSelected.confirm=Sollen jetzt wirklich alle ausgewählten Dateien unwiderruflich gelöscht werden? -file.upload.downloadSelected=Ausgewählte Dateien herunterladen -file.upload.dropArea=Datei auswählen oder hier hinziehen. -file.upload.error.fileAlreadyExists=Die Datei ''{0}'' existiert bereits. -file.upload.error.maxSizeExceeded=Datei ''{0}'' kann nicht hochgeladen werden. Die konfigurierte Maximalgröße wurde überschritten: {1}>{2}. -file.upload.error.maxSizeOfExceeded=Die Datei konnte nicht hochgeladen werden. Die Maximalgröße von {0} wurde überschritten. -file.upload.error.noFileSelected=Keine Datei gewählt -file.upload.error.toManyFiles=Es wurden zu viele Dateien für das gleichzeitige Hochladen ausgewählt. -filing=Ablageort -filter=Filter -filter.all=alle -filter.extendedSearch=Erweiterte Suche -filter.faulty=fehlerhaft -filter.newest=die neuesten -financeAdministration=Finanzbuchhaltung -firstName=Vorname -gender=Geschlecht -gender.diverse=divers -gender.female=weiblich -gender.male=männlich -gender.notApplicable=nicht zutreffend -gender.notKnown=unbekannt -gender.unknown=unbekannt -group=Gruppe -holidays=Feiertage -hours=Stunden -id=Id -imageFile=Bild -inherit=vererbt -key=Schlüssel -language=Sprache -lastUpdate=letzte Änderung -legend=Legende -list=Liste -listView=Listenansicht -loading=Laden... -loggedInUserInfo=Angemeldet als: -longFormat=Langes Format -misc=Verschiedenes -modifications=Änderungen -modificationTime=Änderungszeitraum -modified=geändert -modifiedBy=geändert durch -modifiedHistoryValue=Wert in der Änderungshistorie -moreEntriesAvailable=Mehr Einträge vorhanden. -name=Name -new=Neu -nickname=Rufname -no=Nein -notEnded=nicht beendet -nothingFound=Nichts gefunden. -notLoggedIn=Nicht angemeldet -notVisible=nicht sichtbar -oclock=Uhr -onlyDeleted=nur gelöschte -onlyDeleted.tooltip=Es werden nur gelöschte Datensätze angezeigt (i. d. R. unabhängig von anderen Filterangaben). -operation.deleted=gelöscht -operation.inserted=angelegt -operation.markAsDeleted=als gelöscht markiert -operation.undefined=undefiniert -operation.undeleted=wiederhergestellt -operation.updated=geändert -organization=Firma -password=Passwort -passwordRepeat=Passwort wiederholen -percent=Prozent -pleaseChoose=Bitte wählen -printView=Druckansicht -priority=Priorität -priority.high=hoch -priority.highest=sehr hoch -priority.least=gering -priority.low=niedrig -priority.middle=mittel -priority.without=ohne -quickselect=Schnellauswahl -recursive=rekursiv -rest=Rest -resubmissionOnDate=Wiedervorlage -resumption=Wiedervorlage -searchFilter=Suchfilter -searchString=Suchtext -securityAdvice=Sicherheitshinweis -settings=Einstellungen -shortDescription=Kurzbeschreibung -sql=SQL -statistics=Statistik -status=Status -sum=Summe -task=Strukturelement -templates=Vorlagen -templates.new=Neue Vorlage -text=Text -timeago.afewseconds=vor einigen Sekunden -timeago.days=vor {0} Tagen -timeago.days.one=gestern -timeago.hours=vor {0} Stunden -timeago.hours.one=vor einer Stunde -timeago.minutes=vor {0} Minuten -timeago.minutes.one=vor einer Minute -timeago.months=vor {0} Monaten -timeago.months.one=vor einem Monat -timeago.negative=in der Zukunft! -timeago.seconds=vor {0} Sekunden -timeago.weeks=vor {0} Wochen -timeago.weeks.one=vor einer Woche -timeago.years=vor {0} Jahren -timeago.years.one=vor einem Jahr -timeleft.afewseconds=in einigen Sekunden -timeleft.days=in {0} Tagen -timeleft.days.one=in einem Tag -timeleft.hours=in {0} Stunden -timeleft.hours.one=in einer Stunde -timeleft.minutes=in {0} Minuten -timeleft.minutes.one=in einer Minute -timeleft.months=in {0} Monaten -timeleft.months.one=in einem Monat -timeleft.negative=in der Vergangenheit! -timeleft.seconds=in {0} Sekunden -timeleft.weeks=in {0} Wochen -timeleft.weeks.one=in einer Woche -timeleft.years=in {0} Jahren -timeleft.years.one=in einem Jahr -timeNotation=Uhrzeitformat -timeNotation.12=12 Stunden -timeNotation.24=24 Stunden -timeOfCreation=Anlagezeitpunkt -timeOfLastUpdate=Zeitpunkt der letzten Änderung -timePeriod=Zeitraum -timestamp=Zeitstempel -timezone=Zeitzone -tip=Tipp -title=Titel -totalSum=Gesamtsumme -undefined=undefiniert -until=bis -untitled=unbenannt -user=Benutzer:in -username=Benutzer:innenname -value=Wert -values=Werte -weekOfYear=Kalenderwoche -yes=Ja - access=Zugriffsrecht access.accessTable=Zugriffstabelle access.exception.demoUserHasNoAccess=Der oder die Demobenutzer:in ist für diese Aktion gesperrt. @@ -687,6 +499,7 @@ administration.setup.target.testdata.tooltip=Datenbank mit Testdaten (für Tests administration.setup.title=Erstanmeldung - ProjectForge einrichten administration.title=Administration agGrid.sortInfo=Es können mehrere Spalten sortiert werden, indem die Hochstelltaste beim Anklicken von weiteren Spaltenköpfen gedrückt gehalten wird. Außerdem können Spalten umsortiert und in der Breite verändert werden. +akquise=Akquise attachment=Anhang attachment.checksum=Prüfsumme attachment.encrypt=Verschlüsseln @@ -883,6 +696,10 @@ calendar.view.workDays=Werktage calendar.week=Woche calendar.weekOfYearShortLabel=KW calendar.year=Jahr +changes=Änderungen +charactersLeft=Zeichen übrig. +color.error.unknownFormat=Farbcode kann nicht verarbeitet werden. Unterstützte Hex-Farbformate: #abc or #abcdef +comment=Bemerkung common.attention=Achtung! common.customized=Angepasst common.import.action.commit=Übernehmen @@ -927,6 +744,7 @@ common.resultholder.ok=OK common.resultholder.warning=Warnung common.uploadpanel.filetolarge=Die ausgewählte Datei ist zu groß. Die maximale Größe beträgt {0}. common.uploadpanel.filewrongtype=Die ausgewählte Datei besitzt ein nicht unterstütztes Dateiformat. Unterstützte Formate: {0}. +completed=erledigt contact.birthday=Geburtstag contact.contacts=Adressen contact.emailValues=E-Mailadressen @@ -945,13 +763,30 @@ contact.type.other=andere contact.type.own=eigene contact.type.postal=postalisch contact.type.private=privat +contactPerson=Ansprechpartner:in contextMenu.cancel=Abbrechen contextMenu.newTab=Link in neuem Tab öffnen +created=angelegt +createdBy=angelegt von +date=Datum +date.begin=Beginndatum +date.end=Endedatum +date.from=von +date.until=bis +dateFormat=Datumsformat +dateFormat.xls=Exceldatumsformat +day=Tag(e) +days=Tage +deadline=Frist +default=Standard +deleted=gelöscht +description=Beschreibung dialog.title.error=Es ist ein Fehler aufgetreten! dialog.title.information=Information dialog.title.message=Meldung dialog.title.success=Erfolgsmeldung dialog.title.warning=Warnung +dueDate=Fälligkeit duration.days={0} Tage duration.days.one=1 Tag duration.hours={0} Stunden @@ -961,6 +796,10 @@ duration.minutes.one=1 Minute duration.seconds={0} Sekunden duration.seconds.one=1 Sekunde ### not translated: dvelop.title=D-velop +edit=Bearbeiten +email=E-Mail +ended=beendet +error=Ein Fehler trat auf: {0} error.date.yearOutOfRange=Das Jahr liegt außerhalb des zulässigen Bereichs: ${minimumYear} - ${maximumYear}. error.dateInFuture=Datum darf nicht in der Zukunft liegen. error.endDateBeforeBeginDate=Das Endedatum darf nicht vor dem Anfangsdatum liegen. @@ -975,12 +814,14 @@ errorpage.feedback.messageNumber=Fehlernummer errorpage.feedback.placeholder=Bitte hier beschreiben, wie es zum Fehlverhalten kam. errorpage.title=Ein Fehler ist aufgetreten. errorpage.unknownError=Ein interner Fehler ist aufgetreten. +errors=Fehler exception.constraintViolation=Es trat eine Verletzung der Datenintegrität in der Datenbank auf. Dies kann daran liegen, dass z. B. der aktuelle Datensatz mit einem anderen (ggf. auch gelöschten) kollidiert. exception.flowscope.notExists=Flow existiert nicht (vielleicht auf Grund einer Zeitüberschreitung). Bitte nochmals versuchen. exception.internalError=Es ist ein interner Fehler aufgetreten. Dieser wurde protokolliert. exception.luceneParseError=Fehler bei der Vearbeitung des Suchtextes: {0} exception.pleaseContactDeveloperTeam=Interner Fehler, bitte die Entwickler:innen informieren. Die Fehlerkennung in den Fehlerprotokollen lautet #{0}. exception.scriptError=Fehler bei der Script-Ausführung\: {0} +export=Export feedback.link.tooltip=Feedback senden feedback.mailSendSuccessful=Eine E-Mail wurde erfolgreich versendet. Vielen Dank für die Mithilfe\! feedback.receiver=Empfänger:in @@ -1399,8 +1240,32 @@ fibu.tooltip.unselectKost1=Kost1-Auswahl aufheben fibu.tooltip.unselectKost2=Kost2-Auswahl aufheben fibu.tooltip.unselectKunde=Kundenauswahl aufheben fibu.tooltip.unselectProjekt=Projektauswahl aufheben +fieldNotHistorizable=Dieses Feld wird nicht historisiert! +file=Datei file.panel.deleteExistingFile.heading=Datei wirklich löschen? file.panel.deleteExistingFile.question=Soll die vorhandene Datei wirklich gelöscht bzw. überschrieben werden? +file.upload.audit.action.delete=gelöscht +file.upload.audit.action.download=heruntergeladen +file.upload.audit.action.downloadAll=alles heruntergeladen +file.upload.audit.action.downloadMulti=mehrere heruntergeladen +file.upload.audit.action.modification=geändert (Dateiname oder Beschreibung) +file.upload.audit.action.upload=hochgeladen +file.upload.choose=Datei wählen +file.upload.deleteSelected=Ausgewählte Dateien löschen +file.upload.deleteSelected.confirm=Sollen jetzt wirklich alle ausgewählten Dateien unwiderruflich gelöscht werden? +file.upload.downloadSelected=Ausgewählte Dateien herunterladen +file.upload.dropArea=Datei auswählen oder hier hinziehen. +file.upload.error.fileAlreadyExists=Die Datei ''{0}'' existiert bereits. +file.upload.error.maxSizeExceeded=Datei ''{0}'' kann nicht hochgeladen werden. Die konfigurierte Maximalgröße wurde überschritten: {1}>{2}. +file.upload.error.maxSizeOfExceeded=Die Datei konnte nicht hochgeladen werden. Die Maximalgröße von {0} wurde überschritten. +file.upload.error.noFileSelected=Keine Datei gewählt +file.upload.error.toManyFiles=Es wurden zu viele Dateien für das gleichzeitige Hochladen ausgewählt. +filing=Ablageort +filter=Filter +filter.all=alle +filter.extendedSearch=Erweiterte Suche +filter.faulty=fehlerhaft +filter.newest=die neuesten finance.accountingRecord.dc=SH finance.accountingRecord.dc.credit=Haben finance.accountingRecord.dc.debit=Soll @@ -1408,6 +1273,8 @@ finance.datev.import.error.titleRowMissed=Titelzeile fehlt. ### not translated: finance.datev.upload.hint=*.xls; max. {0} finance.datev.uploadAccountingRecords=Buchungsdaten hochladen finance.datev.uploadAccountList=Konten hochladen +financeAdministration=Finanzbuchhaltung +firstName=Vorname form.ajaxEditableLabel.tooltip=Zum Editieren bitte anklicken. gantt.access.all=Alle gantt.access.owner=Eigner:in @@ -1476,6 +1343,14 @@ gantt.x.unit.day=Tag gantt.x.unit.month=Monat gantt.x.unit.quarter=Quartal gantt.x.unit.week=Woche +gender=Geschlecht +gender.diverse=divers +gender.female=weiblich +gender.male=männlich +gender.notApplicable=nicht zutreffend +gender.notKnown=unbekannt +gender.unknown=unbekannt +group=Gruppe group.assignedUsers=Assoziierte Benutzer:in group.error.groupnameAlreadyExists=Gruppenname ist bereits vergeben. group.groups=Gruppen @@ -1502,6 +1377,8 @@ history.newValue=Neuer Wert history.oldValue=Alter Wert history.propertyName=Feld history.was=war +holidays=Feiertage +hours=Stunden hr.planning.description=Tätigkeit hr.planning.entry.copyFromPredecessor=Vorgänger kopieren hr.planning.entry.error.entryDoesAlreadyExistForUserAndWeekOfYear=Dieser Eintrag kollidiert mit einem bereits vorhandenem für den gleichen Benutzer für die gleiche Kalenderwoche. @@ -1537,6 +1414,8 @@ hr.planning.unassignedHours=ohne Tagangabe hr.planning.view.title=Planungsübersicht hr.planning.weekend=Wochenende hr.planning.workdays=Arbeitstage +id=Id +imageFile=Bild import.confirmMessage=Sollen nun alle ausgewählten Einträge importiert werden? Diese Aktion kann nicht rückgängig gemacht werden. import.display.options=Anzeigeoptionen import.entry.error=Fehler @@ -1571,6 +1450,7 @@ import.title=Import-Tool index.development=Webseite für Entwicklung index.website=Webseite index.welcome=Willkommen bei ProjectForge. +inherit=vererbt jira.chooseProject=--- JIRA-Projekt wählen --- jobs.error.refusedByAnotherRunningJob=Job konnte nicht gestartet werden, weil bereits ein anderer Job für die gleiche Queue läuft. jobs.error.waitingTimeExceeded=Job fehlgeschlagen (Zeitüberschreitung). Der Job konnte nicht gestartet werden, weil er von anderen Job(s) zu lange blockiert wurde. @@ -1589,6 +1469,7 @@ jobs.job.terminatedAt=Beendet jobs.job.title=Jobtitel jobs.monitor.noJobsAvailable=Keine aktuellen Jobs jobs.monitor.title=Jobmonitor +key=Schlüssel label.data=Daten label.exportFormat=Exportformat label.filterSettings=Filtereinstellungen @@ -1606,6 +1487,8 @@ label.script=Script label.script.result=Script-Ergebnis label.sendEMailNotification=E-Mail-Benachrichtigung versenden? label.sendShortMessage=SMS an Bearbeiter versenden? +language=Sprache +lastUpdate=letzte Änderung ldap=LDAP ldap.gidNumber=GID number ldap.gidNumber.alreadyInUse=Die GID-Nummer ist bereits an eine andere Gruppe vergeben. Die nächste freie GID-Nummer lautet: {0}. @@ -1656,7 +1539,11 @@ legalAffaires.contract.type=Typ legalAffaires.contract.validity=Laufzeit legalAffaires.contract.validity.from=Laufzeit von legalAffaires.contract.validity.until=Laufzeit bis +legend=Legende license.upload.title=Lizenzdatei +list=Liste +listView=Listenansicht +loading=Laden... locale.de=Deutsch locale.en=Englisch locale.zh=Chinesisch @@ -1665,6 +1552,7 @@ locale.zh=Chinesisch ### not translated: log.level.info=Info ### not translated: log.level.trace=Trace ### not translated: log.level.warn=Warn +loggedInUserInfo=Angemeldet als: login.adminLoginRequired=Wartungsmodus: Bitte als Administrator:in anmelden! login.error.loginExpired=Die Anmeldung war nicht erfolgreich. Bitte Administrator:in kontaktieren, da der Zugang abgelaufen ist. login.error.loginFailed=Die Anmeldung war nicht erfolgreich. Bitte Eingabe nochmals prüfen (Groß-/Kleinschreibung bitte beachten). @@ -1681,6 +1569,7 @@ login.successful=Anmeldung erfolgreich. Viel Spaß mit ProjectForge! login.timeOffset=Der Zugang ist noch für {0} Sekunden gesperrt auf Grund von {1} Fehlanmeldungen. Bitte später nochmals versuchen. login.title=Anmeldung logout.successful=Erfolgreich abgemeldet. +longFormat=Langes Format mail.error.exception=Beim E-Mailversand trat ein Fehler auf, der protokolliert wurde. Bitte eine:n Systemadministrator:in kontaktieren. mail.error.missingToAddress=Der E-Mailversand wurde abgebrochen, da keine Empfänger:inadresse angegeben ist. mail.template.closing=Viel Spaß mit ProjectForge\! @@ -1790,6 +1679,7 @@ menu.personalStatistics=Meine Statistiken menu.phoneCall=Direktwahl ### not translated: menu.pluginAdmin=Plugins menu.plugins.teamcal=Kalenderliste +menu.poll=Umfragen menu.projectmanagement=Projektmanagement menu.reindexAllDatabaseEntries=Suchindex voll indizieren menu.reindexAllDatabaseEntries.tooltip.content=Der Suchindex wird komplett neu aufgebaut. Bei vielen Einträgen (z. B. 100.000) kann das einige Minuten dauern und die Systemperformance beinträchtigt werden. Deshalb steht diese Funktion nur Administratoren zur Verfügung. @@ -1819,11 +1709,35 @@ message.successfullChanged=Änderung erfolgreich durchgeführt. message.successfullCompleted=Aktion erfolgreich durchgeführt\: {0} message.title=Meldung message.wicket.pageExpired=Die aufgerufene Seite ist nicht mehr verfügbar. +misc=Verschiedenes +modifications=Änderungen +modificationTime=Änderungszeitraum +modified=geändert +modifiedBy=geändert durch +modifiedHistoryValue=Wert in der Änderungshistorie +moreEntriesAvailable=Mehr Einträge vorhanden. multiselection.aggrid.selection.info.message=\ * Gemeinsam mit der Hochstelltaste bzw. Steuerungstaste können mehrere Zeilen per Mausklick gleichzeitig ausgewählt werden.\n\ * Mit den Pfeiltasten kann in den Zeilen navigiert werden und über die Leertaste einzelne Zeilen selektiert und deselektiert werden. multiselection.aggrid.selection.info.title=Mehrfachauswahl multiselection.button=Mehrfachauswahl +name=Name +new=Neu +nickname=Rufname +no=Nein +notEnded=nicht beendet +nothingFound=Nichts gefunden. +notLoggedIn=Nicht angemeldet +notVisible=nicht sichtbar +oclock=Uhr +onlyDeleted=nur gelöschte +onlyDeleted.tooltip=Es werden nur gelöschte Datensätze angezeigt (i. d. R. unabhängig von anderen Filterangaben). +operation.deleted=gelöscht +operation.inserted=angelegt +operation.markAsDeleted=als gelöscht markiert +operation.undefined=undefiniert +operation.undeleted=wiederhergestellt +operation.updated=geändert orga.post.inhalt=Inhalt orga.post.type=Art orga.post.type.brief=Brief @@ -1866,10 +1780,12 @@ orga.visitorbook.visitortype.family=Familie orga.visitorbook.visitortype.normal=Normal orga.visitorbook.visitortype.supplier=Lieferant:in orga.visitorbook.visitortype.workman=Handwerker:in +organization=Firma pacman.title=Pacman panel.error.customernameNotFound=Kundenname nicht existent. panel.error.groupNotFound=Gruppe nicht existent. panel.error.projectNotFound=Projekt nicht existent. +password=Passwort password.forgotten.link=Zugangsdaten vergessen? password.forgotten.mail.subject=Passwortreset ProjectForge® password.forgotten.mailSentTo=E-Mail mit dem Passwortrücksetzen-Link wurde gesendet an ''{0}''. Bitte im Spam-Ordner schauen bzw. überprüfen, ob der Benutzer:innenname bzw. E-Mail korrekt ist. @@ -1881,10 +1797,13 @@ password.reset.mail.message.1=Bitte beachten: Es wird für das Zurücksetzen aus password.reset.mail.message.2=Wenn noch kein zweiter, persönlicher Faktor konfiguriert wurde (Authenticator-App oder Mobilfunknummer), muss ein ProjectForge-Administrator kontaktiert werden. password.reset.title=Passwort zurücksetzen password.reset.username_email=Benutzer:inname/E-Mail +passwordRepeat=Passwort wiederholen +percent=Prozent personal.statistics.timesheetDisciplineChart.title=Zeitnahes Erfassen von Zeitberichten ist ein wichtiger Grundpfeiler erfolgreichen Projektmanagements! personal.statistics.timesheetDisciplineChart1.legend=Insgesamt sind {1} Arbeitszeitstunden in den letzten {0} Tagen angefallen. Bisher wurden für diesen Zeitraum {2} Stunden erfasst. personal.statistics.timesheetDisciplineChart2.legend=In den letzten {0} Tagen wurden Zeitberichte nach durchschnittlich {2} Tagen erfasst. Die Zielgröße ist maximal {1} Tage. personal.statistics.title=Meine Statistiken +pleaseChoose=Bitte wählen plugins.teamcal.access=Zugriffsrecht plugins.teamcal.access.groups=Gruppen plugins.teamcal.access.title=Zugriffsoptionen @@ -2077,6 +1996,166 @@ plugins.teamcal.title.add=Kalender hinzufügen plugins.teamcal.title.edit=Team-Kalender bearbeiten plugins.teamcal.title.heading=Kalender plugins.teamcal.title.list=Kalenderliste +printView=Druckansicht +priority=Priorität +priority.high=hoch +priority.highest=sehr hoch +priority.least=gering +priority.low=niedrig +priority.middle=mittel +priority.without=ohne +quickselect=Schnellauswahl +recursive=rekursiv +rest=Rest +resubmissionOnDate=Wiedervorlage +resumption=Wiedervorlage +searchFilter=Suchfilter +searchString=Suchtext +securityAdvice=Sicherheitshinweis +settings=Einstellungen +shortDescription=Kurzbeschreibung +sql=SQL +statistics=Statistik +status=Status +sum=Summe +task=Strukturelement +templates=Vorlagen +templates.new=Neue Vorlage +text=Text +timeago.afewseconds=vor einigen Sekunden +timeago.days=vor {0} Tagen +timeago.days.one=gestern +timeago.hours=vor {0} Stunden +timeago.hours.one=vor einer Stunde +timeago.minutes=vor {0} Minuten +timeago.minutes.one=vor einer Minute +timeago.months=vor {0} Monaten +timeago.months.one=vor einem Monat +timeago.negative=in der Zukunft! +timeago.seconds=vor {0} Sekunden +timeago.weeks=vor {0} Wochen +timeago.weeks.one=vor einer Woche +timeago.years=vor {0} Jahren +timeago.years.one=vor einem Jahr +timeleft.afewseconds=in einigen Sekunden +timeleft.days=in {0} Tagen +timeleft.days.one=in einem Tag +timeleft.hours=in {0} Stunden +timeleft.hours.one=in einer Stunde +timeleft.minutes=in {0} Minuten +timeleft.minutes.one=in einer Minute +timeleft.months=in {0} Monaten +timeleft.months.one=in einem Monat +timeleft.negative=in der Vergangenheit! +timeleft.seconds=in {0} Sekunden +timeleft.weeks=in {0} Wochen +timeleft.weeks.one=in einer Woche +timeleft.years=in {0} Jahren +timeleft.years.one=in einem Jahr +timeNotation=Uhrzeitformat +timeNotation.12=12 Stunden +timeNotation.24=24 Stunden +timeOfCreation=Anlagezeitpunkt +timeOfLastUpdate=Zeitpunkt der letzten Änderung +timePeriod=Zeitraum +timestamp=Zeitstempel +timezone=Zeitzone +tip=Tipp +title=Titel +totalSum=Gesamtsumme +undefined=undefiniert +until=bis +untitled=unbenannt +user=Benutzer:in +username=Benutzer:innenname +value=Wert +values=Werte +weekOfYear=Kalenderwoche +yes=Ja +# poll plugin +poll=Umfrage +poll.access=Zugriff +poll.answer=Antwort +poll.assignment=Zuordnung +poll.attendee=Teilnehmer:in +poll.attendees=Teilnehmer:innen +poll.button.addQuestion=Eigene Frage hinzuf�gen +poll.button.finish=Umfrage beenden +poll.button.template=Vorlage verwenden +poll.confirmation.creation=M�chtest du die Umfrage wirklich erstellen? Du kannst die Fragen danach nicht mehr bearbeiten.\ +Stelle ebenfalls sicher, dass du Teilnehmer f�r deine Umfrage hinzugef�gt hast. +poll.confirmation.deleteAnswer=M�chtest du diese Antwort wirklich l�schen? +poll.confirmation.deleteQuestion=M�chtest du diese Frage wirklich l�schen? +poll.confirmation.finish=Willst du die Umfrage wirklich beenden? +poll.date=Datum +poll.deadline=Antwortfrist +poll.delegationAnswers=Antworten von +poll.description=Beschreibung +poll.error.oneQuestionRequired=Mindestens eine Frage ist erforderlich. +poll.exception.noAttendee=Dieser Nutzer ist nicht Teil der Umfrage. +poll.export.response.poll=Ergebnisse exportieren +poll.finished=Beendet +poll.fullAccessGroups=Gruppen mit Vollzugriff +poll.fullAccessUsers=Benutzer:innen mit Vollzugriff +poll.groupAttendees=Teilnehmergruppen +poll.guide=Anleitung +poll.infopage=Infoseite +poll.location=Ort +poll.mail.ended.content=

Liebe Teilnehmerinnen und Teilnehmer,

\ +

wir m�chten Sie dar�ber informieren, dass die Umfrage "{0}", erstellt von {1}, nun abgeschlossen ist. Vielen Dank an alle, die teilgenommen und wertvolles Feedback gegeben haben.

\ +

Falls Sie den Einsendeschluss verpasst haben, m�chten wir Sie dennoch ermutigen, uns Ihre Gedanken mitzuteilen. Auch wenn wir Ihre Antworten m�glicherweise nicht in den offiziellen Ergebnissen ber�cksichtigen k�nnen, ist Ihr Feedback dennoch wertvoll f�r zuk�nftige Umfragen und Initiativen.

\ +

Nochmals vielen Dank f�r Ihre Teilnahme.

\ +
\ +

Freundliche Gr��e,

\ +

{1}

+poll.mail.ended.subject=Umfrage beendet +poll.mail.endingSoon.content=

Liebe Teilnehmerinnen und Teilnehmer,

\ +

wir m�chten Sie daran erinnern, dass die Umfrage "{0}", erstellt von {1}, bald endet, n�mlich am {2}. Bitte achten Sie darauf, Ihre Antworten vor dem Ablaufdatum einzureichen.

\ +

Falls Sie noch nicht die Gelegenheit hatten, an der Umfrage teilzunehmen, nehmen Sie sich bitte einen Moment Zeit, um dies zu tun, bevor die Umfrage geschlossen wird. Ihre Meinung ist wichtig und wertvoll.

\ +

{3}

\ +

Vielen Dank f�r Ihre Aufmerksamkeit und einen sch�nen Tag!

\ +
\ +

Freundliche Gr��e,

\ +

{1}

+poll.mail.endingSoon.subject=Umfrage endet in {0} Tagen +poll.mail.update.content=

Liebe Teilnehmerinnen und Teilnehmer,

\ +

Wir m�chten Ihnen mitteilen, dass die Umfrage "{0}" k�rzlich bearbeitet wurde.

\ +

Falls Sie bereits Ihre Antworten eingereicht haben, sollten Sie �berpr�fen, ob wesentliche �nderungen vorgenommen wurden.

\ +

Nochmals vielen Dank f�r Ihre Teilnahme.

\ +

Freundliche Gr��e,

\ +

{1}

+poll.mail.update.subject=Umfrage wurde bearbeitet +poll.other=Andere +poll.owner=Eigent�mer:in +poll.popup.closed=Umfrage wurde bereits beendet +poll.question=Frage +poll.question.textQuestion=Textfrage +poll.questionType=Fragen Typ +poll.respond=Antworten abschicken +### not translated: poll.response.mail.update.content=

Dear {0},

\ +#

I wanted to inform you that Person {2} has updated their answer to Poll {1}.

\ +#

If you were not notified about this,

\ +#

I recommend reaching out to the person directly or adjusting your results accordingly.

\ +#

You can modify your response until "{3}".

\ +#

Best regards,

\ +#

{2}

+### not translated: poll.response.mail.update.subject=Response was edited by {0} +poll.response.page=Seite zur Umfrageantwort +poll.response.title=Seite zur Umfrageantwort +poll.running=Aktiv +poll.selectUser=Nutzer ausw�hlen +poll.state=Status +poll.title=Titel +poll.title.add=Neue Umfrage erstellen +poll.title.edit=Umfrage bearbeiten +poll.title.list=Umfragen +poll.userDelegation=F�r andere Nutzer abstimmen +poll.yourAnswers=Deine Antworten +poll.manual.title=Anleitung, um eine Umfrage zu erstellen | Als Erstes muss man die Hauptinformationen der Umfrage ausf�llen. +poll.manual.questions=Anschließend werden die Fragen der Umfrage angelegt. Die Fragen können aus verschiedenen Typen bestehen. +poll.manual.singleResponse=Eine Frage, die bei der man eine Antwort auswählen kann. Beispielsweise für eine simple Ja oder Nein Frage. +poll.manual.multiResponse=Eine Frage, die bei der man eine Antwort auswählen kann. Gut geeignet für eine Datumsumfrage für Verf�gbarkeiten. +poll.manual.textQuestion=Eine Frage, die bei der man mit Freitext antworten kann. Gut geeignet für formloses Feedback. projectmanagement.personDays=Personentage projectmanagement.personDays.short=PT question.deleteQuestion=Soll das Objekt wirklich unwiderruflich gelöscht werden? @@ -2682,7 +2761,6 @@ webauthn.registration.button.authenticate=WebAuthn webauthn.registration.button.authenticate.info=Du kannst hier registrierte WebAuthn-Token benutzen (z. B. Yubikey). webauthn.registration.button.register=Registrieren webauthn.title=WebAuthn (Fido2 etc.) - # (timeable) attributes attr.deletemodal.heading=Soll dieser Eintrag wirklich gelöscht werden? attr.deletemodal.question=Ja: Der Eintrag wird gelöscht und alle Änderungen auf dieser Seite werden gespeichert.
Abbrechen: Der Eintrag wird nicht gelöscht und Sie bleiben auf dieser Seite. @@ -2692,7 +2770,6 @@ attr.savemodal.question=Ja: Alle Änderungen auf dieser Seite werden gesp attr.starttime.alreadyexists.day=Es existiert bereits ein Eintrag mit gleichem Datum (Tag). attr.starttime.alreadyexists.month=Es existiert bereits ein Eintrag mit gleichem Datum (Monat). attr.validFrom=Gültig ab - birthdayButler.email.content=Anbei die Liste der Geburtstage für den nächsten Monat.
Diese E-Mail wurde automatisch von ProjectForge generiert. birthdayButler.email.content.noBirthdaysFound=No birthdays found for this month.
This E-Mail is automatically generated by ProjectForge. birthdayButler.email.subject=Geburtstagsliste für diff --git a/projectforge-business/src/main/resources/flyway/migrate/common/V7.5.1.2__7.5.1.0-POLL.sql b/projectforge-business/src/main/resources/flyway/migrate/common/V7.5.1.2__7.5.1.0-POLL.sql new file mode 100644 index 0000000000..a704b6b02d --- /dev/null +++ b/projectforge-business/src/main/resources/flyway/migrate/common/V7.5.1.2__7.5.1.0-POLL.sql @@ -0,0 +1,43 @@ +-- Table with synchronize infos (Sipgate) + +CREATE TABLE T_POLL +( + pk INTEGER NOT NULL, + deleted BOOLEAN NOT NULL, + created TIMESTAMP WITHOUT TIME ZONE, + last_update TIMESTAMP WITHOUT TIME ZONE, + title CHARACTER VARYING(1000) NOT NULL, + description CHARACTER VARYING(1000), + location CHARACTER VARYING(1000), + owner_fk INTEGER NOT NULL, + deadline DATE NOT NULL, + state CHARACTER VARYING(1000) NOT NULL, + attendeeIds VARCHAR(5000), + groupAttendeeIds VARCHAR(5000), + full_access_user_ids CHARACTER VARYING(255), + full_access_group_ids CHARACTER VARYING(255), + inputFields CHARACTER Varying(100000) +); + +ALTER TABLE T_POLL + ADD CONSTRAINT t_poll_pkey PRIMARY KEY (pk); +ALTER TABLE T_POLL + ADD CONSTRAINT fk_t_poll_pf_user FOREIGN KEY (owner_fk) REFERENCES t_pf_user (pk); + +CREATE TABLE T_POLL_RESPONSE +( + pk INTEGER NOT NULL, + deleted BOOLEAN NOT NULL, + created TIMESTAMP WITHOUT TIME ZONE, + last_update TIMESTAMP WITHOUT TIME ZONE, + poll_fk INTEGER NOT NULL, + owner_fk INTEGER NOT NULL, + responses CHARACTER Varying(10000) +); + +ALTER TABLE T_POLL_RESPONSE + ADD CONSTRAINT t_poll_response_pkey PRIMARY KEY (pk); +ALTER TABLE T_POLL_RESPONSE + ADD CONSTRAINT fk_t_poll_response_pf_user FOREIGN KEY (owner_fk) REFERENCES t_pf_user (pk); +ALTER TABLE T_POLL_RESPONSE + ADD CONSTRAINT fk_t_poll_response_poll FOREIGN KEY (poll_fk) REFERENCES t_poll (pk); \ No newline at end of file diff --git a/projectforge-business/src/main/resources/officeTemplates/PollResultTemplate.xlsx b/projectforge-business/src/main/resources/officeTemplates/PollResultTemplate.xlsx new file mode 100644 index 0000000000..c88023f767 Binary files /dev/null and b/projectforge-business/src/main/resources/officeTemplates/PollResultTemplate.xlsx differ diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/Poll.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/Poll.kt new file mode 100644 index 0000000000..671b336cf5 --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/Poll.kt @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll + +import com.fasterxml.jackson.databind.ObjectMapper +import org.projectforge.business.poll.PollDO +import org.projectforge.framework.persistence.user.entities.PFUserDO +import org.projectforge.rest.dto.BaseDTO +import org.projectforge.rest.dto.Group +import org.projectforge.rest.dto.User +import org.projectforge.rest.poll.types.Question +import java.time.LocalDate + +class Poll( + var title: String? = null, + var description: String? = null, + var owner: PFUserDO? = null, + var location: String? = null, + var deadline: LocalDate? = null, + var state: PollDO.State? = PollDO.State.RUNNING, + var questionType: String? = null, + var inputFields: MutableList? = mutableListOf(), + var fullAccessGroups: List? = null, + var fullAccessUsers: List? = null, + var groupAttendees: List? = null, + var attendees: List? = null, + var delegationUser: User? = null +) : BaseDTO() { + override fun copyFrom(src: PollDO) { + super.copyFrom(src) + fullAccessGroups = Group.toGroupList(src.fullAccessGroupIds) + fullAccessUsers = User.toUserList(src.fullAccessUserIds) + groupAttendees = Group.toGroupList(src.groupAttendeeIds) + attendees = User.toUserList(src.attendeeIds) + if (src.inputFields != null) { + val fields = ObjectMapper().readValue(src.inputFields, MutableList::class.java) + inputFields = fields.map { Question().toObject(ObjectMapper().writeValueAsString(it)) }.toMutableList() + } + } + + override fun copyTo(dest: PollDO) { + super.copyTo(dest) + dest.fullAccessGroupIds = Group.toIntList(fullAccessGroups) + dest.fullAccessUserIds = User.toIntList(fullAccessUsers) + dest.groupAttendeeIds = Group.toIntList(groupAttendees) + dest.attendeeIds = User.toIntList(attendees) + if (inputFields != null) { + dest.inputFields = ObjectMapper().writeValueAsString(inputFields) + } + } + + fun isAlreadyCreated(): Boolean { + return id != null + } + + fun isFinished(): Boolean { + return state == PollDO.State.FINISHED + } +} diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollCronJobs.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollCronJobs.kt new file mode 100644 index 0000000000..61513bfa30 --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollCronJobs.kt @@ -0,0 +1,156 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll + +import org.projectforge.business.poll.PollDO +import org.projectforge.business.poll.PollDao +import org.projectforge.business.poll.PollResponseDao +import org.projectforge.framework.i18n.translateMsg +import org.projectforge.mail.MailAttachment +import org.projectforge.rest.poll.excel.ExcelExport +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.web.bind.annotation.RestController +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter +import java.time.temporal.ChronoUnit + +@RestController +class PollCronJobs { + + @Autowired + private lateinit var pollDao: PollDao + + @Autowired + private lateinit var pollResponseDao: PollResponseDao + + @Autowired + private lateinit var pollMailService: PollMailService + + @Autowired + private lateinit var exporter: ExcelExport + + private val log: Logger = LoggerFactory.getLogger(PollCronJobs::class.java) + + /** + * Cron job for daily stuff + */ + + @Scheduled(cron = "0 0 1 * * *") // 1am everyday + fun dailyCronJobs() { + log.info("Start daily cron jobs") + cronDeletePolls() + cronEndPolls() + } + + /** + * Method to end polls after deadline + */ + private fun cronEndPolls() { + val pollDOs = pollDao.internalLoadAll() + // set State.FINISHED for all old polls and export excel + pollDOs.forEach { pollDO -> + // try to send mail until successfully changed to FINISHED_AND_MAIL_SENT + if (pollDO.state != PollDO.State.FINISHED_AND_MAIL_SENT) { + if (pollDO.deadline?.isBefore(LocalDate.now()) == true) { + pollDO.state = PollDO.State.FINISHED + + try { + val poll = Poll() + poll.copyFrom(pollDO) + + val excel = exporter.getExcel(poll) + + val mailAttachment = object : MailAttachment { + override fun getFilename(): String { + return "${pollDO.title}_${LocalDateTime.now().year}_Result.xlsx" + } + + override fun getContent(): ByteArray? { + return excel + } + } + // add all attendees mails + val mailTo: ArrayList = + ArrayList(poll.attendees?.map { it.email }?.mapNotNull { it } ?: emptyList()) + val mailFrom = pollDO.owner?.email.toString() + val mailSubject = translateMsg("poll.mail.ended.subject") + val mailContent = translateMsg("poll.mail.ended.content", pollDO.title, pollDO.owner?.displayName) + + pollDao.internalSaveOrUpdate(pollDO) + log.info("Set state of poll (${pollDO.id}) ${pollDO.title} to FINISHED") + pollMailService.sendMail(mailFrom, mailTo, mailContent, mailSubject, listOf(mailAttachment)) + pollDO.state = PollDO.State.FINISHED_AND_MAIL_SENT + } catch (e: Exception) { + log.error(e.message, e) + } + } + } + } + + val pollsInFuture = pollDOs.filter { it.deadline?.isAfter(LocalDate.now()) ?: false } + pollsInFuture.forEach { pollDO -> + val poll = Poll() + poll.copyFrom(pollDO) + val daysDifference = ChronoUnit.DAYS.between(LocalDate.now(), pollDO.deadline) + if (daysDifference == 1L || daysDifference == 7L) { + // add all attendees mails + val mailTo: ArrayList = + ArrayList(poll.attendees?.map { it.email }?.mapNotNull { it } ?: emptyList()) + val mailFrom = pollDO.owner?.email.toString() + val mailSubject = translateMsg("poll.mail.endingSoon.subject", daysDifference) + val mailContent = translateMsg( + "poll.mail.endingSoon.content", + pollDO.title, + pollDO.owner?.displayName, + pollDO.deadline?.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")).toString(), + "https://projectforge.micromata.de/react/response/dynamic/${pollDO.id}" + ) + pollMailService.sendMail(mailFrom, mailTo, mailSubject, mailContent) + } + } + } + + /** + * Method to delete old polls + */ + private fun cronDeletePolls() { + val polls = pollDao.internalLoadAll() + val pollsMoreThanOneYearPast = polls.filter { + it.deadline?.isBefore(LocalDate.now().minusYears(1)) == true + } + pollsMoreThanOneYearPast.forEach { poll -> + val pollResponses = pollResponseDao.internalLoadAll().filter { response -> + response.poll?.id == poll.id + } + pollResponses.forEach { + pollResponseDao.internalMarkAsDeleted(it) + } + pollDao.internalMarkAsDeleted(poll) + } + } +} diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollInfoPageRest.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollInfoPageRest.kt new file mode 100644 index 0000000000..251143011b --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollInfoPageRest.kt @@ -0,0 +1,124 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll + +import org.projectforge.framework.i18n.translate +import org.projectforge.rest.config.Rest +import org.projectforge.rest.core.AbstractDynamicPageRest +import org.projectforge.rest.dto.FormLayoutData +import org.projectforge.ui.* +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import javax.servlet.http.HttpServletRequest + + +@RestController +@RequestMapping("${Rest.URL}/pollInfo") +class PollInfoPageRest : AbstractDynamicPageRest() { + + @GetMapping("dynamic") + fun getForm(request: HttpServletRequest): FormLayoutData { + + val layout = UILayout("poll.infopage") + val field = UIFieldset() + .add( + UILabel("poll.manual.title") + ) + + field.add( + UICol() + .add(UIReadOnlyField("title", label = "title", value = translate("poll.title"))) + ) + field.add( + UICol() + .add(UIReadOnlyField("description", label = "description", value = translate("poll.description"))) + ) + field.add( + UICol() + .add(UIReadOnlyField("location", label = "location", value = translate("poll.location"))) + ) + field.add( + UICol() + .add(UIReadOnlyField("owner", label = "owner", value = translate("poll.owner"))) + ) + field.add( + UICol() + .add(UIReadOnlyField("deadline", label = "deadline", value = translate("poll.deadline"))) + ) + + field.add( + UIRow().add( + UICol().add( + UILabel("poll.manual.questions") + ) + ) + ) + + layout.add(field) + + layout.add( + UIFieldset().add(UILabel("Single Response " + translate("poll.question"))).add( + UICol() + .add( + UIReadOnlyField( + "question", + label = "poll.question", + value = translate("poll.manual.singleResponse") + ) + ) + ) + ) + layout.add( + UIFieldset().add(UILabel("Multiple Response " + translate("poll.question"))).add( + UICol() + .add( + UIReadOnlyField( + "question", + label = "poll.question", + value = translate("poll.manual.multiResponse") + ) + ) + ) + ) + layout.add( + UIFieldset().add(UILabel("Text " + translate("poll.question"))).add( + UICol() + .add( + UIReadOnlyField( + "question", + label = "poll.question", + value = translate("poll.manual.textQuestion") + ) + ) + + ) + ) + + + LayoutUtils.process(layout) + + return FormLayoutData(null, layout, createServerData(request)) + } +} diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollMailService.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollMailService.kt new file mode 100644 index 0000000000..b3da91e1cf --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollMailService.kt @@ -0,0 +1,104 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll + +import org.projectforge.business.group.service.GroupService +import org.projectforge.business.user.service.UserService +import org.projectforge.mail.Mail +import org.projectforge.mail.MailAttachment +import org.projectforge.mail.SendMail +import org.projectforge.rest.dto.User +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Service +class PollMailService { + + @Autowired + private lateinit var sendMail: SendMail + + @Autowired + private lateinit var groupService: GroupService + + @Autowired + private lateinit var userService: UserService + + private val log: Logger = LoggerFactory.getLogger(PollMailService::class.java) + + fun sendMail( + from: String, + to: List, + subject: String, + content: String, + mailAttachments: List? = null + ) { + try { + if (content.isNotEmpty() && to.isNotEmpty()) { + val mail = Mail() + mail.subject = subject + mail.contentType = Mail.CONTENTTYPE_HTML + mail.content = content + mail.from = from + to.forEach { mail.addTo(it) } + sendMail.send(mail, attachments = mailAttachments) + log.info("Mail with subject $subject sent to $to") + } else { + log.error("There are missing parameters for sending mail: from: $from, to: $to, subject: $subject, content: $content") + } + } catch (e: Exception) { + log.error(e.message, e) + } + + } + + fun getAllMails(poll: Poll): List { + val attendees = poll.attendees + var fullAccessUser = poll.fullAccessUsers?.toMutableList() ?: mutableListOf() + val accessGroupIds = poll.fullAccessGroups?.filter { it.id != null }?.map { it.id!! }?.toIntArray() + val accessUserIds = UserService().getUserIds(groupService.getGroupUsers(accessGroupIds)) + val accessUsers = User.toUserList(accessUserIds) + + accessUsers?.forEach { user -> + if (fullAccessUser.none { it.id == user.id }) { + fullAccessUser.add(user) + } + } + + var owner = User.getUser(poll.owner?.id, false) + if (owner != null) { + fullAccessUser.add(owner) + } + attendees?.forEach { + if (!fullAccessUser.contains(it)) { + fullAccessUser.add(it) + } + } + + User.restoreDisplayNames(fullAccessUser, userService) + return fullAccessUser.mapNotNull { it.email } + } + +} \ No newline at end of file diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollPageRest.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollPageRest.kt new file mode 100644 index 0000000000..0258998323 --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollPageRest.kt @@ -0,0 +1,671 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll + +import com.fasterxml.jackson.databind.ObjectMapper +import org.projectforge.business.group.service.GroupService +import org.projectforge.business.poll.PollDO +import org.projectforge.business.poll.PollDao +import org.projectforge.business.poll.PollResponseDao +import org.projectforge.business.poll.filter.PollAssignment +import org.projectforge.business.poll.filter.PollAssignmentFilter +import org.projectforge.business.poll.filter.PollState +import org.projectforge.business.poll.filter.PollStateFilter +import org.projectforge.business.user.service.UserService +import org.projectforge.framework.access.AccessException +import org.projectforge.framework.i18n.translate +import org.projectforge.framework.i18n.translateMsg +import org.projectforge.framework.persistence.api.MagicFilter +import org.projectforge.framework.persistence.api.QueryFilter +import org.projectforge.framework.persistence.api.impl.CustomResultFilter +import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext +import org.projectforge.menu.MenuItem +import org.projectforge.menu.MenuItemTargetType +import org.projectforge.rest.config.Rest +import org.projectforge.rest.config.RestUtils +import org.projectforge.rest.core.* +import org.projectforge.rest.dto.* +import org.projectforge.rest.poll.excel.ExcelExport +import org.projectforge.rest.poll.types.BaseType +import org.projectforge.rest.poll.types.PREMADE_QUESTIONS +import org.projectforge.rest.poll.types.Question +import org.projectforge.ui.* +import org.projectforge.ui.filter.UIFilterListElement +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.core.io.Resource +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.* +import java.time.LocalDate +import java.time.LocalDateTime +import java.util.* +import javax.servlet.http.HttpServletRequest + +@RestController +@RequestMapping("${Rest.URL}/poll") +class PollPageRest : AbstractDTOPagesRest(PollDao::class.java, "poll.title") { + + private val log: Logger = LoggerFactory.getLogger(PollPageRest::class.java) + + @Autowired + private lateinit var userService: UserService + + @Autowired + private lateinit var groupService: GroupService + + @Autowired + private lateinit var pollMailService: PollMailService + + @Autowired + private lateinit var pollDao: PollDao + + @Autowired + private lateinit var excelExport: ExcelExport + + @Autowired + private lateinit var pollResponseDao: PollResponseDao + + override fun newBaseDTO(request: HttpServletRequest?): Poll { + val result = Poll() + result.owner = ThreadLocalUserContext.user + return result + } + + override fun onBeforeMarkAsDeleted(request: HttpServletRequest, obj: PollDO, postData: PostData) { + val responsesToDelete = pollResponseDao.internalLoadAll().filter { + it.poll?.id == obj.id + } + responsesToDelete.forEach { + pollResponseDao.markAsDeleted(it) + } + super.onBeforeMarkAsDeleted(request, obj, postData) + } + + + override fun transformForDB(dto: Poll): PollDO { + val pollDO = PollDO() + dto.copyTo(pollDO) + if (dto.inputFields != null) { + pollDO.inputFields = ObjectMapper().writeValueAsString(dto.inputFields) + } + return pollDO + } + + + // override fun transformForDB editMode not used + override fun transformFromDB(obj: PollDO, editMode: Boolean): Poll { + val poll = Poll() + poll.copyFrom(obj) + User.restoreDisplayNames(poll.fullAccessUsers, userService) + Group.restoreDisplayNames(poll.fullAccessGroups, groupService) + User.restoreDisplayNames(poll.attendees, userService) + Group.restoreDisplayNames(poll.groupAttendees, groupService) + return poll + } + + /** + * @return the response page. + */ + override fun getStandardEditPage(): String { + return "${PagesResolver.getDynamicPageUrl(PollResponsePageRest::class.java)}?pollId=:id" + } + + override fun createListLayout( + request: HttpServletRequest, layout: UILayout, magicFilter: MagicFilter, userAccess: UILayout.UserAccess + ) { + val pollLC = LayoutContext(lc) + layout.add( + UITable.createUIResultSetTable() + .add(pollLC, "title", "description", "location", "owner", "deadline", "state") + ) + } + + override fun addMagicFilterElements(elements: MutableList) { + elements.add( + UIFilterListElement("assignment", label = translate("poll.assignment"), defaultFilter = true) + .buildValues(PollAssignment.OWNER, PollAssignment.ACCESS, PollAssignment.ATTENDEE, PollAssignment.OTHER) + ) + elements.add( + UIFilterListElement("status", label = translate("poll.state"), defaultFilter = true) + .buildValues(PollState.RUNNING, PollState.FINISHED) + ) + } + + override fun preProcessMagicFilter(target: QueryFilter, source: MagicFilter): List> { + val filters = mutableListOf>() + val assignmentFilterEntry = source.entries.find { it.field == "assignment" } + if (assignmentFilterEntry != null) { + assignmentFilterEntry.synthetic = true + val values = assignmentFilterEntry.value.values + if (!values.isNullOrEmpty()) { + val enums = values.map { PollAssignment.valueOf(it) } + filters.add(PollAssignmentFilter(enums)) + } + } + val statusFilterEntry = source.entries.find { it.field == "status" } + if (statusFilterEntry != null) { + statusFilterEntry.synthetic = true + val values = statusFilterEntry.value.values + if (!values.isNullOrEmpty()) { + val enums = values.map { PollState.valueOf(it) } + filters.add(PollStateFilter(enums)) + } + } + return filters + } + + + override fun createEditLayout(dto: Poll, userAccess: UILayout.UserAccess): UILayout { + val layout = super.createEditLayout(dto, userAccess) + val fieldset = UIFieldset(UILength(12)) + layout.add(fieldset) + if (dto.isFinished() && dto.isAlreadyCreated()) { + layout.add( + MenuItem( + "export-poll-response-button", + i18nKey = "poll.export.response.poll", + url = RestResolver.getRestUrl( + restClass = PollPageRest::class.java, + subPath = "export", + params = mapOf("id" to dto.id) + ), + type = MenuItemTargetType.DOWNLOAD + ) + ) + } + + layout.add( + MenuItem( + "poll-guide", + i18nKey = "poll.guide", + url = PagesResolver.getDynamicPageUrl(PollInfoPageRest::class.java, absolute = false), + type = MenuItemTargetType.MODAL + ) + ) + + + addDefaultParameterFields(dto, fieldset, isRunning = dto.state == PollDO.State.RUNNING) + + fieldset + .add(UISelect.createUserSelect(lc, "fullAccessUsers", true, "poll.fullAccessUsers")) + .add(UISelect.createGroupSelect(lc, "fullAccessGroups", true, "poll.fullAccessGroups")) + .add(UISelect.createUserSelect(lc, "attendees", true, "poll.attendees")) + .add(UISelect.createGroupSelect(lc, "groupAttendees", true, "poll.groupAttendees")) + if (!dto.isAlreadyCreated()) { + fieldset.add( + UIRow() + .add( + UICol(UILength(xs = 9, sm = 9, md = 9, lg = 9)) + .add( + UISelect( + "questionType", + values = BaseType.values().map { UISelectValue(it, it.name) }, + label = "poll.questionType" + ) + ) + ) + .add( + UICol(UILength(xs = 3, sm = 3, md = 3, lg = 3)) + .add(UISpacer()) + .add( + UIButton.createDefaultButton( + id = "add-question-button", + title = "poll.button.addQuestion", + responseAction = ResponseAction( + "${Rest.URL}/poll/add", + targetType = TargetType.PUT + ), + default = false + ) + ) + ) + ) + .add( + UIRow() + .add( + UICol(UILength(xs = 9, sm = 9, md = 9, lg = 9)) + ) + .add( + UICol(UILength(xs = 3, sm = 3, md = 3, lg = 3)) + .add( + UIButton.createDefaultButton( + id = "template-button", + responseAction = ResponseAction( + "${Rest.URL}/poll/addPremadeQuestions", + targetType = TargetType.PUT + ), + title = "poll.button.template", + default = false + ) + ) + ) + ) + } + addQuestionFieldset(layout, dto, fieldset) + + layout.watchFields.add("delegationUser") + layout.watchFields.addAll(listOf("groupAttendees")) + + + val processedLayout = LayoutUtils.processEditPage(layout, dto, this) + if (!dto.isFinished()) { + processedLayout.actions.filterIsInstance().find { + it.id == "create" + }?.confirmMessage = translateMsg("poll.confirmation.creation") + + + if (dto.isAlreadyCreated()) { + processedLayout.addAction( + UIButton.createDangerButton( + id = "poll-button-finish", + title = "poll.button.finish", + confirmMessage = translateMsg("poll.confirmation.finish"), + responseAction = ResponseAction( + "${Rest.URL}/poll/finish", + targetType = TargetType.PUT + ), + layout = layout, + ) + ) + } + } + + return processedLayout + } + + + @PutMapping("/finish") + fun changeStateToFinish( + request: HttpServletRequest, + @RequestBody postData: PostData + ): ResponseEntity { + postData.data.state = PollDO.State.FINISHED + postData.data.deadline = LocalDate.now() + return super.saveOrUpdate(request, postData) + } + + + override fun onBeforeSaveOrUpdate(request: HttpServletRequest, obj: PollDO, postData: PostData) { + if (obj.inputFields.isNullOrEmpty() || obj.inputFields.equals("[]")) { + throw AccessException("poll.error.oneQuestionRequired") + } + + super.onBeforeSaveOrUpdate(request, obj, postData) + } + + + override fun onAfterSaveOrUpdate(request: HttpServletRequest, obj: PollDO, postData: PostData) { + // add all attendees mails + var mailTo = pollMailService.getAllMails(postData.data) + + val owner = userService.getUser(obj.owner?.id) + val mailFrom = owner?.email.toString() + val mailSubject: String + val mailContent: String + + if (postData.data.isAlreadyCreated()) { + mailSubject = translateMsg("poll.mail.update.subject") + mailContent = translateMsg( + "poll.mail.update.content", obj.title, owner?.displayName + ) + } else { + mailSubject = translateMsg("poll.mail.created.subject") + mailContent = translateMsg( + "poll.mail.created.content", obj.title, owner?.displayName + ) + } + pollMailService.sendMail(mailFrom, mailTo, mailSubject, mailContent) + + super.onAfterSaveOrUpdate(request, obj, postData) + } + + + @PostMapping("/addAnswer/{fieldId}") + fun addAnswerForMultipleChoice( + @RequestBody postData: PostData, + @PathVariable("fieldId") fieldUid: String, + ): ResponseEntity { + val dto = postData.data + + val found = dto.inputFields?.find { it.uid == fieldUid } + found?.answers?.add("") + dto.owner = userService.getUser(dto.owner?.id) + return ResponseEntity.ok( + ResponseAction(targetType = TargetType.UPDATE).addVariable("data", dto).addVariable( + "ui", + createEditLayout(dto, getUserAccess(dto)) + ) + ) + } + + // PostMapping add + @PutMapping("/add") + fun addQuestionField( + @RequestBody postData: PostData + ): ResponseEntity { + val dto = postData.data + + val type = dto.questionType?.let { BaseType.valueOf(it) } ?: BaseType.TextQuestion + val question = Question(uid = UUID.randomUUID().toString(), type = type) + if (type == BaseType.SingleResponseQuestion) { + question.answers = mutableListOf("yes", "no") + } + + dto.inputFields?.add(question) + dto.owner = userService.getUser(dto.owner?.id) + return ResponseEntity.ok( + ResponseAction(targetType = TargetType.UPDATE).addVariable("data", dto) + .addVariable("ui", createEditLayout(dto, getUserAccess(dto))) + ) + } + + override fun onWatchFieldsUpdate( + request: HttpServletRequest, + dto: Poll, + watchFieldsTriggered: Array? + ): ResponseEntity { + if (watchFieldsTriggered?.get(0) == "groupAttendees") { + val groupIds = dto.groupAttendees?.filter { it.id != null }?.map { it.id!! }?.toIntArray() + val userIds = UserService().getUserIds(groupService.getGroupUsers(groupIds)) + val users = User.toUserList(userIds) + User.restoreDisplayNames(users, userService) + val allUsers = dto.attendees?.toMutableList() ?: mutableListOf() + + users?.forEach { user -> + if (allUsers.none { it.id == user.id }) { + allUsers.add(user) + } + } + + dto.groupAttendees = mutableListOf() + dto.attendees = allUsers.sortedBy { it.displayName } + } + dto.owner = userService.getUser(dto.owner?.id) + + // I don't know why this is necessary + if (watchFieldsTriggered?.get(0) == "delegationUser") { + dto.delegationUser = dto.delegationUser + } + dto.owner = userService.getUser(dto.owner?.id) + return ResponseEntity.ok( + ResponseAction( + targetType = TargetType.UPDATE + ) + .addVariable("ui", createEditLayout(dto, getUserAccess(dto))) + .addVariable("data", dto) + ) + } + + + @PutMapping("/addPremadeQuestions") + private fun addPremadeQuestionsField( + @RequestBody postData: PostData, + ): ResponseEntity { + val dto = postData.data + + PREMADE_QUESTIONS.entries.forEach { entry -> + dto.inputFields?.add(entry.value) + } + + return ResponseEntity.ok( + ResponseAction(targetType = TargetType.UPDATE).addVariable("data", dto) + .addVariable("ui", createEditLayout(dto, getUserAccess(dto))) + ) + } + + + private fun addQuestionFieldset(layout: UILayout, dto: Poll, fieldset: UIFieldset) { + fieldset.add(UISpacer()) + dto.inputFields?.forEachIndexed { index, field -> + val questionFieldset = UIFieldset(UILength(12), title = field.type.toString()) + if (!dto.isAlreadyCreated()) { + questionFieldset.add(generateDeleteButton(layout, field.uid)) + } + questionFieldset.add( + getUiElement( + dto.isAlreadyCreated(), + "inputFields[${index}].question", + translateMsg("poll.question") + ) + ) + + if (field.type == BaseType.SingleResponseQuestion || field.type == BaseType.MultiResponseQuestion) { + field.answers?.forEachIndexed { answerIndex, _ -> + questionFieldset.add( + generateSingleAndMultiResponseAnswer( + dto.isAlreadyCreated(), + index, + field.uid, + answerIndex, + layout, + field.answers!!.size + ) + ) + .add(UISpacer()) + } + if (!dto.isAlreadyCreated()) { + questionFieldset.add( + UIRow() + .add( + UIButton.createAddButton( + responseAction = ResponseAction( + "${Rest.URL}/poll/addAnswer/${field.uid}", targetType = TargetType.POST + ), + default = false + ) + ) + ) + } + } + + fieldset.add(questionFieldset) + } + } + + + private fun generateSingleAndMultiResponseAnswer( + objGiven: Boolean, + inputFieldIndex: Int, + questionUid: String?, + answerIndex: Int, + layout: UILayout, + answerAmount: Int, + ): UIRow { + val row = UIRow() + row.add( + UICol() + .add( + getUiElement( + objGiven, + "inputFields[${inputFieldIndex}].answers[${answerIndex}]", + translateMsg("poll.answer") + " ${answerIndex + 1}" + ) + ) + ) + if (!objGiven) { + // require at least two answers + if (answerAmount > 2) { + row.add( + UICol() + .add(UISpacer()) + .add( + UIButton.createDangerButton( + id = "X", + responseAction = ResponseAction( + "${Rest.URL}/poll/deleteAnswer/${questionUid}/${answerIndex}", + targetType = TargetType.POST + ) + ).withConfirmMessage(layout, confirmMessage = "poll.confirmation.deleteAnswer") + ) + ) + } + } + + return row + } + + + @PostMapping("/deleteAnswer/{questionUid}/{answerIndex}") + fun deleteAnswerOfSingleAndMultipleResponseQuestion( + @RequestBody postData: PostData, + @PathVariable("questionUid") questionUid: String, + @PathVariable("answerIndex") answerIndex: Int + ): ResponseEntity { + val dto = postData.data + + dto.inputFields?.find { it.uid.equals(questionUid) }?.answers?.removeAt(answerIndex) + dto.owner = userService.getUser(dto.owner?.id) + return ResponseEntity.ok( + ResponseAction(targetType = TargetType.UPDATE).addVariable("data", dto) + .addVariable("ui", createEditLayout(dto, getUserAccess(dto))) + ) + } + + + private fun generateDeleteButton(layout: UILayout, uid: String?): UIRow { + val row = UIRow() + row.add( + UICol(UILength(11)) + ) + .add( + UICol(length = UILength(1)) + .add( + UIButton.createDangerButton( + id = "X", + responseAction = ResponseAction( + "${Rest.URL}/poll/deleteQuestion/${uid}", targetType = TargetType.POST + ) + ).withConfirmMessage(layout, confirmMessage = "poll.confirmation.deleteQuestion") + ) + ) + return row + } + + + @PostMapping("/deleteQuestion/{uid}") + fun deleteQuestion( + @RequestBody postData: PostData, + @PathVariable("uid") uid: String, + ): ResponseEntity { + val dto = postData.data + val userAccess = UILayout.UserAccess(insert = true, update = true) + + val matchingQuestion: Question? = dto.inputFields?.find { it.uid.equals(uid) } + dto.inputFields?.remove(matchingQuestion) + + return ResponseEntity.ok( + ResponseAction(targetType = TargetType.UPDATE).addVariable("data", dto) + .addVariable("ui", createEditLayout(dto, userAccess)) + ) + } + + + @GetMapping("export") + fun export(@RequestParam("id") id: String): ResponseEntity? { + val poll = Poll() + val pollDo = pollDao.getById(id.toInt()) + poll.copyFrom(pollDo) + User.restoreDisplayNames(poll.attendees, userService) + val bytes: ByteArray? = excelExport + .getExcel(poll) + val filename = ("${poll.title}_${LocalDateTime.now().year}_Result.xlsx") + + if (bytes == null || bytes.isEmpty()) { + log.error("Oops, xlsx is empty. Filename: $filename") + return null + } + log.info("Exporting $filename") + return RestUtils.downloadFile(filename, bytes) + } + + + companion object { + /** + * Once created, questions should be ReadOnly + */ + @JvmStatic + fun getUiElement( + isReadOnly: Boolean, + id: String, + label: String? = null, + dataType: UIDataType = UIDataType.STRING + ): UIElement { + return if (isReadOnly) + UIReadOnlyField(id, label = label, dataType = dataType) + else + UIInput(id, label = label, dataType = dataType) + } + } + + + private fun addDefaultParameterFields(pollDto: Poll, fieldset: UIFieldset, isRunning: Boolean) { + if (isRunning) { + fieldset + .add(lc, "title", "description", "location") + .add(UISelect.createUserSelect(lc, "owner", false, "poll.owner")) + .add(lc, "deadline") + } else { + fieldset + .add(UIReadOnlyField(value = pollDto.title, label = "titel", dataType = UIDataType.STRING)) + .add(UIReadOnlyField(value = pollDto.description, label = "description", dataType = UIDataType.STRING)) + .add(UIReadOnlyField(value = pollDto.location, label = "location", dataType = UIDataType.STRING)) + .add( + UIReadOnlyField( + value = pollDto.deadline.toString(), + label = "deadline", + dataType = UIDataType.STRING + ) + ) + .add(UIReadOnlyField(value = pollDto.owner?.displayName, label = "owner", dataType = UIDataType.STRING)) + } + } + + + /** + * restricts the user access accordingly + */ + private fun getUserAccess(pollDto: Poll): UILayout.UserAccess { + val pollDO = PollDO() + pollDto.copyTo(pollDO) + + return if (!pollDao.hasFullAccess(pollDO)) { + // no full access user + UILayout.UserAccess(insert = false, update = false, delete = false, history = false) + } else { + if (!pollDto.isAlreadyCreated()) { + // full access when creating new poll + UILayout.UserAccess(insert = true, update = true, delete = false, history = true) + } else { + if (pollDto.isFinished()) { + // full access when viewing finished poll + UILayout.UserAccess(insert = false, update = false, delete = true, history = false) + } + // full access when viewing old poll + UILayout.UserAccess(insert = true, update = true, delete = true, history = false) + } + } + } + +} diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollResponsePageRest.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollResponsePageRest.kt new file mode 100644 index 0000000000..1e2a81ef24 --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/PollResponsePageRest.kt @@ -0,0 +1,358 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll + +import com.fasterxml.jackson.databind.ObjectMapper +import org.projectforge.business.poll.PollDO +import org.projectforge.business.poll.PollDao +import org.projectforge.business.poll.PollResponseDO +import org.projectforge.business.poll.PollResponseDao +import org.projectforge.business.poll.filter.PollAssignment +import org.projectforge.business.user.service.UserService +import org.projectforge.framework.access.AccessException +import org.projectforge.framework.i18n.translateMsg +import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext +import org.projectforge.framework.persistence.user.entities.PFUserDO +import org.projectforge.framework.utils.NumberHelper +import org.projectforge.menu.MenuItem +import org.projectforge.menu.MenuItemTargetType +import org.projectforge.model.rest.RestPaths +import org.projectforge.rest.config.Rest +import org.projectforge.rest.core.AbstractDynamicPageRest +import org.projectforge.rest.core.PagesResolver +import org.projectforge.rest.core.RestResolver +import org.projectforge.rest.dto.FormLayoutData +import org.projectforge.rest.dto.PostData +import org.projectforge.rest.poll.types.* +import org.projectforge.ui.* +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.* +import java.time.format.DateTimeFormatter +import java.util.* +import javax.servlet.http.HttpServletRequest +import javax.validation.Valid + + +@RestController +@RequestMapping("${Rest.URL}/pollResponse") +class PollResponsePageRest : AbstractDynamicPageRest() { + + @Autowired + private lateinit var pollDao: PollDao + + @Autowired + private lateinit var pollResponseDao: PollResponseDao + + @Autowired + private lateinit var pollMailService: PollMailService + + @Autowired + private lateinit var userService: UserService + + private var pollId: Int? = null + private var questionOwnerId: Int? = null + + @GetMapping("dynamic") + fun getForm( + request: HttpServletRequest, + @RequestParam("pollId") pollStringId: String?, + @RequestParam("questionOwner") delUser: String?, + @RequestParam("returnToCaller") returnToCaller: String?, + ): FormLayoutData { + if (pollId === null || pollStringId != null) { + pollId = NumberHelper.parseInteger(pollStringId) ?: throw IllegalArgumentException("id not given.") + } + // used to load answers, is an attendee chosen by a fullAccessUser in order to answer for them or the ThreadLocal User + val pollData = pollDao.internalGetById(pollId) ?: PollDO() + + val answerTitle: String + if (delUser != null && pollDao.hasFullAccess(pollData) && pollDao.isAttendee(pollData, delUser.toInt())) { + questionOwnerId = delUser.toInt() + answerTitle = translateMsg("poll.delegationAnswers") + userService.getUser(questionOwnerId).displayName + } else { + questionOwnerId = ThreadLocalUserContext.userId + answerTitle = translateMsg("poll.yourAnswers") + } + + + val pollDto = transformPollFromDB(pollData) + + if (pollData.id == null) { + throw AccessException("access.exception.noAccess", "Umfrage nicht gefunden.") + } + + // allow access to attendee, full access and owner + if (pollData.getPollAssignment().contains(PollAssignment.OTHER)) { + throw AccessException("access.exception.noAccess", "Du darfst nicht auf diese Umfrage antworten.") + } + + val layout = UILayout("poll.response.title") + if (pollDao.hasFullAccess(pollData)) { + layout.add( + MenuItem( + "EDIT", + i18nKey = "poll.title.edit", + url = PagesResolver.getEditPageUrl(PollPageRest::class.java, pollDto.id), + type = MenuItemTargetType.REDIRECT + ) + ) + } + + val fieldset = UIFieldset(12, title = pollDto.title + " - " + answerTitle) + layout.add(fieldset) + fieldset.add(UIReadOnlyField(value = pollDto.description, label = translateMsg("poll.description"))) + .add(UIReadOnlyField(value = pollDto.location, label = translateMsg("poll.location"))) + .add(UIReadOnlyField(value = pollDto.owner?.displayName, label = translateMsg("poll.owner"))) + .add(UIReadOnlyField(value = pollDto.deadline.toString(), label = translateMsg("poll.deadline"))) + .add(UISpacer()) + .add(UISpacer()) + + if (!pollDto.isFinished() && ThreadLocalUserContext.userId === questionOwnerId) { + val fieldSetDelegationUser = UIFieldset(title = "poll.userDelegation") + fieldSetDelegationUser.add( + UIInput( + id = "delegationUser", + label = "user", + dataType = UIDataType.USER + ) + ) + .add(UISpacer()) + .add( + UIButton.createDefaultButton( + id = "response-poll-button", + responseAction = ResponseAction( + RestResolver.getRestUrl( + this::class.java, + "showDelegatedUser" + ), + targetType = TargetType.GET + ), + title = "poll.selectUser" + ), + ) + layout.add(fieldSetDelegationUser) + } + + val pollResponse = PollResponse() + pollResponse.poll = pollData + + pollResponseDao.internalLoadAll().firstOrNull { response -> + response.owner?.id == questionOwnerId + && response.poll?.id == pollData.id + }?.let { + pollResponse.copyFrom(it) + } + + pollDto.inputFields?.forEachIndexed { index, field -> + val fieldSetQuestions = UIFieldset(title = field.question) + val questionAnswer = QuestionAnswer() + questionAnswer.uid = UUID.randomUUID().toString() + questionAnswer.questionUid = field.uid + pollResponse.responses?.firstOrNull { + it.questionUid == field.uid + }.let { + if (it == null) pollResponse.responses?.add(questionAnswer) + } + + val col = UICol() + + if (field.type == BaseType.TextQuestion) { + col.add( + PollPageRest.getUiElement( + pollDto.isFinished(), + "responses[$index].answers[0]", + "poll.question.textQuestion", + UIDataType.STRING + ) + ) + } + + if (field.type == BaseType.MultiResponseQuestion || field.type === BaseType.SingleResponseQuestion) { + field.answers?.forEachIndexed { index2, _ -> + if (pollResponse.responses?.get(index)?.answers?.getOrNull(index2) == null) { + pollResponse.responses?.get(index)?.answers?.add(index2, false) + } + if (field.type == BaseType.MultiResponseQuestion) { + col.add( + UICheckbox( + "responses[$index].answers[$index2]", + label = field.answers?.get(index2) ?: "" + ) + ) + } else { + col.add( + UIRadioButton( + "responses[$index].answers[0]", + value = field.answers?.get(index2) ?: "", + label = field.answers?.get(index2) ?: "" + ) + ) + } + } + } + fieldSetQuestions.add(UIRow().add(col)) + fieldset.add(fieldSetQuestions) + } + + val backUrl = if (returnToCaller.isNullOrEmpty()) { + PagesResolver.getListPageUrl(PollPageRest::class.java, absolute = true) + } else { + // Fix doubled encoding: + returnToCaller.replace("%2F", "/") + } + layout.add( + UIButton.createBackButton( + responseAction = ResponseAction( + backUrl, + targetType = TargetType.REDIRECT + ), + default = true + ) + ) + + if (!pollDto.isFinished()) { + layout.add( + UIButton.createDefaultButton( + id = "addResponse", + title = translateMsg("poll.respond"), + responseAction = ResponseAction( + RestResolver.getRestUrl( + this::class.java, + "addResponse" + ) + "/?questionOwner=${questionOwnerId}", targetType = TargetType.POST + ) + ) + ) + } + + layout.watchFields.add("delegationUser") + LayoutUtils.process(layout) + return FormLayoutData(pollResponse, layout, createServerData(request)) + } + + @PostMapping("addResponse") + fun addResponse( + request: HttpServletRequest, + @RequestBody postData: PostData, @RequestParam("questionOwner") questionOwner: Int? + ): ResponseEntity? { + val pollResponseDO = PollResponseDO() + postData.data.copyTo(pollResponseDO) + + pollResponseDO.owner = userService.getUser(questionOwner) + pollResponseDao.internalLoadAll().firstOrNull { pollResponse -> + pollResponse.owner?.id == questionOwner + && pollResponse.poll?.id == postData.data.poll?.id + }?.let { + it.responses = pollResponseDO.responses + pollResponseDao.update(it) + return ResponseEntity.ok( + ResponseAction( + targetType = TargetType.REDIRECT, + url = PagesResolver.getListPageUrl(PollPageRest::class.java, absolute = true) + ) + ) + } + + pollResponseDao.saveOrUpdate(pollResponseDO) + + if (ThreadLocalUserContext.user != pollResponseDO.owner) { + sendMailResponseToOwner(pollResponseDO, ThreadLocalUserContext.user!!) + } + + return ResponseEntity.ok( + ResponseAction( + targetType = TargetType.REDIRECT, + url = PagesResolver.getListPageUrl(PollPageRest::class.java, absolute = true) + ) + ) + } + + private fun sendMailResponseToOwner(pollResponseDO: PollResponseDO, canedUser: PFUserDO) { + val emailList = ArrayList() + pollResponseDO.owner?.email?.let { emailList.add(it) } + pollMailService.sendMail( + canedUser.email.toString(), emailList, + translateMsg("poll.response.mail.update.subject", canedUser.displayName), + translateMsg( + "poll.response.mail.update.content", + pollResponseDO.owner?.displayName, + pollResponseDO.poll?.title, + canedUser.displayName, + pollResponseDO.poll?.deadline?.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")).toString() + ) + ) + } + + @GetMapping("showDelegatedUser") + fun showDelegatedUser( + request: HttpServletRequest + ): ResponseEntity? { + val attendees = listOfNotNull( + pollDao.internalGetById(pollId).attendeeIds, + pollDao.internalGetById(pollId).fullAccessUserIds, + pollDao.internalGetById(pollId).owner?.id + ) + val joinedAttendeeIds = attendees.joinToString(", ") + if (questionOwnerId == ThreadLocalUserContext.userId) { + return ResponseEntity.ok( + ResponseAction() + ) + } + if (joinedAttendeeIds.split(", ").any { it.toInt() == questionOwnerId }) { + return ResponseEntity.ok( + ResponseAction( + url = "/react/response/dynamic?pollId=${pollId}&questionOwner=${questionOwnerId}", + targetType = TargetType.REDIRECT + ) + ) + } else { + return ResponseEntity.badRequest().body( + ResponseAction( + url = "/react/poll", + targetType = TargetType.REDIRECT, + message = ResponseAction.Message("poll.exception.noAttendee") + ) + ) + } + } + + + @PostMapping(RestPaths.WATCH_FIELDS) + fun watchFields(@Valid @RequestBody postData: PostData): ResponseEntity { + questionOwnerId = postData.data.delegationUser?.id + return ResponseEntity.ok(ResponseAction(targetType = TargetType.UPDATE)) + } + + + private fun transformPollFromDB(obj: PollDO): Poll { + val poll = Poll() + poll.copyFrom(obj) + if (obj.inputFields != null) { + val a = ObjectMapper().readValue(obj.inputFields, MutableList::class.java) + poll.inputFields = a.map { Question().toObject(ObjectMapper().writeValueAsString(it)) }.toMutableList() + } + return poll + } +} \ No newline at end of file diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/excel/ExcelExport.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/excel/ExcelExport.kt new file mode 100644 index 0000000000..31e14ef09d --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/excel/ExcelExport.kt @@ -0,0 +1,242 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll.excel + +import de.micromata.merlin.excel.ExcelRow +import de.micromata.merlin.excel.ExcelSheet +import de.micromata.merlin.excel.ExcelWorkbook +import org.apache.poi.ss.usermodel.CellStyle +import org.apache.poi.ss.usermodel.HorizontalAlignment +import org.apache.poi.ss.util.CellRangeAddress +import org.projectforge.business.group.service.GroupService +import org.projectforge.business.poll.PollResponseDao +import org.projectforge.business.user.service.UserService +import org.projectforge.rest.dto.User +import org.projectforge.rest.poll.Poll +import org.projectforge.rest.poll.types.BaseType +import org.projectforge.rest.poll.types.PollResponse +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.core.io.ClassPathResource +import org.springframework.stereotype.Service +import java.io.IOException +import java.util.* + +@Service +class ExcelExport { + + private val log: Logger = LoggerFactory.getLogger(ExcelExport::class.java) + + private val FIRST_DATA_ROW_NUM = 2 + + @Autowired + private lateinit var pollResponseDao: PollResponseDao + + @Autowired + private lateinit var groupService: GroupService + + @Autowired + private lateinit var userService: UserService + + + fun getExcel(poll: Poll): ByteArray? { + val responses = pollResponseDao.internalLoadAll().filter { it.poll?.id == poll.id } + val classPathResource = ClassPathResource("officeTemplates/PollResultTemplate" + ".xlsx") + + try { + ExcelWorkbook(classPathResource.inputStream, classPathResource.file.name).use { workbook -> + val excelSheet = workbook.getSheet(0) + val style = workbook.createOrGetCellStyle() + excelSheet.autosize(0) + val emptyRow = excelSheet.getRow(0) + var anzNewRows = 2 + + anzNewRows += (poll.attendees?.size ?: 0) + + createNewRow(excelSheet, emptyRow, anzNewRows) + setFirstRow(excelSheet, style, poll) + + + + poll.attendees?.sortedBy { it.displayName } + poll.attendees?.forEachIndexed { index, user -> + val res = PollResponse() + responses.find { it.owner?.id == user.id }?.let { res.copyFrom(it) } + setNewRows(excelSheet, poll, user, res, index + FIRST_DATA_ROW_NUM) + } + + val fullAccessUser = poll.fullAccessUsers?.toMutableList() ?: mutableListOf() + val accessGroupIds = poll.fullAccessGroups?.filter { it.id != null }?.map { it.id!! }?.toIntArray() + val accessUserIds = UserService().getUserIds(groupService.getGroupUsers(accessGroupIds)) + val accessUsers = User.toUserList(accessUserIds) + User.restoreDisplayNames(accessUsers, userService) + + accessUsers?.forEach { user -> + if (fullAccessUser.none { it.id == user.id }) { + fullAccessUser.add(user) + } + } + + var owner = User.getUser(poll.owner?.id, false) + if (owner != null) { + fullAccessUser.add(owner) + } + + User.restoreDisplayNames(fullAccessUser, userService) + fullAccessUser.forEachIndexed { _, user -> + var number = (anzNewRows) + if (poll.attendees?.map { it.id }?.contains(user.id) == false) { + val res = PollResponse() + responses.find { it.owner?.id == user.id }?.let { res.copyFrom(it) } + // User add a Response + if (res.id != null) { + // Put data in the Row + setNewRows(excelSheet, poll, user, res, number) + } + } + } + + return returnByteFile(excelSheet) + } + } catch (e: NullPointerException) { + e.printStackTrace() + } catch (e: IOException) { + e.printStackTrace() + } + return null + } + + + private fun setFirstRow(excelSheet: ExcelSheet, style: CellStyle, poll: Poll) { + val excelRow = excelSheet.getRow(0) + val excelRow1 = excelSheet.getRow(1) + + style.alignment = HorizontalAlignment.CENTER + + var merge = 1 + poll.inputFields?.forEach { question -> + val answers = question.answers + if (question.type == BaseType.MultiResponseQuestion || question.type == BaseType.SingleResponseQuestion) { + var counter = merge + question.answers?.forEach { answer -> + excelRow1.getCell(counter).setCellValue(answer) + excelRow1.getCell(counter).setCellStyle(style) + excelSheet.autosize(counter) + counter++ + } + excelRow.getCell(merge).setCellValue(question.question) + excelSheet.autosize(merge) + counter-- + answers?.size?.let { + if (it >= 2) { + excelSheet.addMergeRegion(CellRangeAddress(0, 0, merge, counter)) + } + } + merge = counter + } else { + excelRow.getCell(merge).setCellValue(question.question) + excelRow.setCellStyle(style) + excelSheet.autosize(merge) + } + merge += 1 + } + excelRow.setHeight(30F) + } + + private fun setNewRows(excelSheet: ExcelSheet, poll: Poll, user: User, res: PollResponse?, rowNumber: Int) { + val excelRow = excelSheet.getRow(rowNumber) + + + excelRow.getCell(0).setCellValue(user.displayName) + excelSheet.autosize(0) + var cell = 0 + + var largestAnswer = "" + poll.inputFields?.forEachIndexed { _, question -> + val questionAnswer = res?.responses?.find { it.questionUid == question.uid } + + if (questionAnswer?.answers.isNullOrEmpty()) { + cell += question.answers?.size ?: 0 + } + questionAnswer?.answers?.forEachIndexed { ind, answer -> + cell++ + if (question.type == BaseType.MultiResponseQuestion) { + if (answer is Boolean && answer == true) { + excelRow.getCell(cell).setCellValue("X") + } + } else if (question.type == BaseType.SingleResponseQuestion) { + if (answer is String && answer.equals(question.answers?.get(ind))) { + excelRow.getCell(cell).setCellValue("X") + } + } else { + excelRow.getCell(cell).setCellValue(answer.toString()) + if (countLines(answer.toString()) > countLines(largestAnswer)) { + largestAnswer = answer.toString() + } + } + excelSheet.autosize(cell) + } + } + + val puffer: String = largestAnswer + var counterOfBreaking = 0 + var counterOfOverlength = 0 + + val pufferSplit: Array = + puffer.split("\r\n|\r|\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + // check for line-breaks + for (i in pufferSplit.indices) { + counterOfBreaking++ + counterOfOverlength += pufferSplit[i].length / 70 + } + excelRow.setHeight((14 + counterOfOverlength * 14 + counterOfBreaking * 14).toFloat()) + } + + private fun countLines(str: String): Int { + val lines = str.split("\r\n|\r|\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + return lines.size + } + + private fun createNewRow(excelSheet: ExcelSheet?, emptyRow: ExcelRow?, anzNewRows: Int) { + if (excelSheet == null || emptyRow == null) { + log.error("in createNewRow(...) excelSheet or emptyRow is null") + return + } + for (i in 1 until anzNewRows) { + Objects.requireNonNull( + excelSheet.getRow(FIRST_DATA_ROW_NUM) + ).copyAndInsert( + emptyRow.sheet + ) + } + } + + private fun returnByteFile(excelSheet: ExcelSheet): ByteArray? { + excelSheet.excelWorkbook.use { workbook -> + val byteArrayOutputStream = workbook.asByteArrayOutputStream + return byteArrayOutputStream.toByteArray() + } + } +} \ No newline at end of file diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/PollResponse.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/PollResponse.kt new file mode 100644 index 0000000000..39cd28a03c --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/PollResponse.kt @@ -0,0 +1,61 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll.types + +import com.fasterxml.jackson.databind.ObjectMapper +import org.projectforge.business.poll.PollDO +import org.projectforge.business.poll.PollResponseDO +import org.projectforge.framework.persistence.user.entities.PFUserDO +import org.projectforge.rest.dto.BaseDTO + +class PollResponse : BaseDTO() { + var poll: PollDO? = null + var owner: PFUserDO? = null + var responses: MutableList? = mutableListOf() + override fun copyTo(dest: PollResponseDO) { + if (!this.responses.isNullOrEmpty()) { + dest.responses = ObjectMapper().writeValueAsString(this.responses) + } + super.copyTo(dest) + } + + override fun copyFrom(src: PollResponseDO) { + if (!src.responses.isNullOrEmpty()) { + val a = ObjectMapper().readValue(src.responses, MutableList::class.java) + this.responses = a.map { QuestionAnswer().toObject(ObjectMapper().writeValueAsString(it)) }.toMutableList() + } + super.copyFrom(src) + } +} + +class QuestionAnswer { + var uid: String? = null + var questionUid: String? = "" + var answers: MutableList? = mutableListOf() + + + fun toObject(string: String): QuestionAnswer { + return ObjectMapper().readValue(string, QuestionAnswer::class.java) + } +} diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/PremadeQuestions.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/PremadeQuestions.kt new file mode 100644 index 0000000000..9caac1bc82 --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/PremadeQuestions.kt @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll.types + +import java.util.UUID + + +val PREMADE_QUESTIONS = mapOf( + "HAS_FOOD" to Question( + uid = UUID.randomUUID().toString(), + question = "Was willst du essen?", + type = BaseType.SingleResponseQuestion, + answers = mutableListOf("Fleisch", "Vegetarisch", "Vegan") + ), + "IS_REMOTE" to Question( + uid = UUID.randomUUID().toString(), + question = "Nimmst du remote teil?", + type = BaseType.SingleResponseQuestion, + answers = mutableListOf("Ja", "Nein") + ), + "CAN_HAVE_COMPANIONS" to Question( + uid = UUID.randomUUID().toString(), + question = "Nimmst du eine Begleitung mit? (Name der Begleitung)", + type = BaseType.TextQuestion, + answers = mutableListOf("") + ), + "CAN_HAVE_CHILDREN" to Question( + uid = UUID.randomUUID().toString(), + question = "Nimmst du ein Kind mit? (Name der Begleitung)", + type = BaseType.TextQuestion, + answers = mutableListOf("") + ), + "CAN_STAY_OVERNIGHT" to Question( + uid = UUID.randomUUID().toString(), + question = "Willst du dort übernachten?", + type = BaseType.SingleResponseQuestion, + answers = mutableListOf("Ja", "Nein") + ), + "HAS_BREAKFAST" to Question( + uid = UUID.randomUUID().toString(), + question = "Willst du am nächsten Tag frühstücken?", + type = BaseType.SingleResponseQuestion, + answers = mutableListOf("Ja", "Nein") + ), +) diff --git a/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/Question.kt b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/Question.kt new file mode 100644 index 0000000000..fcdc45c6a1 --- /dev/null +++ b/projectforge-rest/src/main/kotlin/org/projectforge/rest/poll/types/Question.kt @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project ProjectForge Community Edition +// www.projectforge.org +// +// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com) +// +// ProjectForge is dual-licensed. +// +// This community edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation; version 3 of the License. +// +// This community edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +// Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see http://www.gnu.org/licenses/. +// +///////////////////////////////////////////////////////////////////////////// + +package org.projectforge.rest.poll.types + +import com.fasterxml.jackson.databind.ObjectMapper + + +class Question( + val uid: String? = null, + val question: String? = "", + val type: BaseType? = BaseType.TextQuestion, + var answers: MutableList? = mutableListOf(""), + var parent: String? = null, + var isRequired: Boolean? = false, + var numberOfSelect: Int? = 1, +) { + fun toObject(string: String): Question { + return ObjectMapper().readValue(string, Question::class.java) + } + + fun toJson(): String { + return ObjectMapper().writeValueAsString(this) + } +} + +enum class BaseType { + TextQuestion, SingleResponseQuestion, MultiResponseQuestion, +}