Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 8.1 snapshot #281

Merged
merged 4 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion projectforge-application/src/main/resources/i18nKeys.json
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,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.AuftragsCacheService","org.projectforge.business.fibu.EingangsrechnungsPositionDO","org.projectforge.business.fibu.EmployeeSalaryDao","org.projectforge.business.fibu.EmployeeServiceSupport","org.projectforge.business.fibu.InvoiceService","org.projectforge.business.fibu.ProjektDO","org.projectforge.business.fibu.RechnungDao","org.projectforge.business.fibu.RechnungService","org.projectforge.business.fibu.RechnungsPositionDO","org.projectforge.business.fibu.kost.Kost1DO","org.projectforge.business.fibu.kost.Kost1Dao","org.projectforge.business.fibu.kost.Kost2ArtDao","org.projectforge.business.fibu.kost.Kost2DO","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.HRPlanningDao","org.projectforge.business.humanresources.HRPlanningEntryDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.orga.VisitorbookDO","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.business.vacation.model.VacationDO","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.json.IdOnlySerializer","org.projectforge.framework.persistence.api.BaseDao","org.projectforge.framework.persistence.candh.CandHMaster","org.projectforge.framework.persistence.database.DatabaseService","org.projectforge.framework.persistence.database.ReindexerRegistry","org.projectforge.framework.persistence.database.ReindexerStrategy","org.projectforge.framework.persistence.entities.DefaultBaseDO","org.projectforge.framework.persistence.jpa.PfPersistenceContext","org.projectforge.framework.persistence.search.HibernateSearchDependentObjectsReindexer","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.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.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.EmployeeValidSinceAttrPageRest","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.VisitorbookEntryPageRest","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.EingangsrechnungEditPage","org.projectforge.web.fibu.Kost2ArtEditForm","org.projectforge.web.fibu.Kost2ArtListPage","org.projectforge.web.fibu.RechnungEditPage","org.projectforge.web.gantt.GanttTreeTableNode","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.AuftragsCacheService","org.projectforge.business.fibu.EingangsrechnungsPositionDO","org.projectforge.business.fibu.EmployeeSalaryDao","org.projectforge.business.fibu.EmployeeServiceSupport","org.projectforge.business.fibu.InvoiceService","org.projectforge.business.fibu.ProjektDO","org.projectforge.business.fibu.RechnungDao","org.projectforge.business.fibu.RechnungService","org.projectforge.business.fibu.RechnungsPositionDO","org.projectforge.business.fibu.kost.Kost1DO","org.projectforge.business.fibu.kost.Kost1Dao","org.projectforge.business.fibu.kost.Kost2ArtDao","org.projectforge.business.fibu.kost.Kost2DO","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.HRPlanningDao","org.projectforge.business.humanresources.HRPlanningEntryDO","org.projectforge.business.orga.ContractDao","org.projectforge.business.orga.VisitorbookDO","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.business.vacation.model.VacationDO","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.json.IdOnlySerializer","org.projectforge.framework.persistence.api.BaseDao","org.projectforge.framework.persistence.candh.CandHMaster","org.projectforge.framework.persistence.database.DatabaseService","org.projectforge.framework.persistence.database.ReindexerRegistry","org.projectforge.framework.persistence.database.ReindexerStrategy","org.projectforge.framework.persistence.entities.DefaultBaseDO","org.projectforge.framework.persistence.history.HistoryService","org.projectforge.framework.persistence.jpa.PfPersistenceContext","org.projectforge.framework.persistence.search.HibernateSearchDependentObjectsReindexer","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.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.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.EmployeeValidSinceAttrPageRest","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.VisitorbookEntryPageRest","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.EingangsrechnungEditPage","org.projectforge.web.fibu.Kost2ArtEditForm","org.projectforge.web.fibu.Kost2ArtListPage","org.projectforge.web.fibu.RechnungEditPage","org.projectforge.web.gantt.GanttTreeTableNode","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":[]},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import jakarta.persistence.criteria.CriteriaBuilder
import org.apache.commons.collections4.CollectionUtils
import org.apache.commons.lang3.ArrayUtils
import org.apache.commons.lang3.StringUtils
import org.projectforge.business.sipgate.SipgateDeleteContactService
import org.projectforge.business.teamcal.event.TeamEventDao
import org.projectforge.common.StringHelper
import org.projectforge.framework.access.AccessException
Expand Down Expand Up @@ -75,6 +76,9 @@ open class AddressDao : BaseDao<AddressDO>(AddressDO::class.java) {
@Autowired
private lateinit var personalAddressDao: PersonalAddressDao

@Autowired
private lateinit var sipgateDeleteContactService: SipgateDeleteContactService

@Autowired
private lateinit var teamEventDao: TeamEventDao

Expand Down Expand Up @@ -324,6 +328,7 @@ open class AddressDao : BaseDao<AddressDO>(AddressDO::class.java) {
persistenceService.runInTransaction { context ->
personalAddressDao.internalDeleteAll(obj)
teamEventDao.removeAttendeeByAddressIdFromAllEvents(obj)
sipgateDeleteContactService.deleteContact(obj.id!!)
val counter = context.executeNamedUpdate(
AddressImageDO.DELETE_ALL_IMAGES_BY_ADDRESS_ID,
Pair("addressId", obj.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ import mu.KotlinLogging
import org.projectforge.business.user.ProjectForgeGroup
import org.projectforge.framework.access.OperationType
import org.projectforge.framework.configuration.ConfigXml
import org.projectforge.framework.persistence.history.HistoryFormatUtils
import org.projectforge.framework.persistence.history.HistoryLoadContext
import org.projectforge.framework.persistence.user.entities.PFUserDO
import org.projectforge.framework.time.PFDateTime.Companion.now
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.io.File
import java.io.FilenameFilter
Expand All @@ -43,6 +46,9 @@ private val log = KotlinLogging.logger {}
*/
@Service
open class ScriptDao : AbstractScriptDao() {
@Autowired
private lateinit var historyFormatUtils: HistoryFormatUtils

/**
* Copy old script as script backup if modified.
*
Expand Down Expand Up @@ -114,4 +120,8 @@ open class ScriptDao : AbstractScriptDao() {
ProjectForgeGroup.FINANCE_GROUP
)
}

override fun customizeDisplayHistoryEntry(context: HistoryLoadContext) {
historyFormatUtils.replaceGroupAndUserIdsValues(context.requiredDisplayHistoryEntry)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ScriptExecutionResult(val scriptLogger: ScriptLogger) : Serializable {
@Transient
var result: Any? = null
@Transient
var exception: Exception? = null
var exception: Throwable? = null
var output: String? = null
/**
* The effective script (including any auto-imports and bindings).
Expand Down Expand Up @@ -59,7 +59,7 @@ class ScriptExecutionResult(val scriptLogger: ScriptLogger) : Serializable {
} else HtmlHelper.escapeHtml(result.toString(), true)

fun hasException(): Boolean {
return exception != null
return exception != null || result is Throwable
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ import org.projectforge.framework.json.IdOnlySerializer
]
)
@NamedQueries(
NamedQuery(
name = SipgateContactSyncDO.DELETE_BY_ADDRESS_ID,
query = "delete from SipgateContactSyncDO where address.id = :addressId"
),
NamedQuery(
name = SipgateContactSyncDO.FIND_BY_ADDRESS_ID,
query = "from SipgateContactSyncDO where address.id = :addressId"
Expand Down Expand Up @@ -235,6 +239,7 @@ open class SipgateContactSyncDO {
return sb.toString().trim()
}

const val DELETE_BY_ADDRESS_ID = "SipgateContactSyncDO_deleteByAddressId"
const val FIND_BY_CONTACT_AND_ADDRESS_ID = "SipgateContactSyncDO_findByContactAndAddressId"
const val FIND_BY_ADDRESS_ID = "SipgateContactSyncDO_findByAddressId"
const val LOAD_ALL = "SipgateContactSyncDO_loadAll"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2025 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.sipgate

import org.projectforge.framework.persistence.jpa.PfPersistenceService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

/**
* Used by AddressDao if addresses are forced to be deleted.
* @author K. Reinhard ([email protected])
*/
@Service
class SipgateDeleteContactService {
@Autowired
private lateinit var persistenceService: PfPersistenceService

fun deleteContact(addressId: Long) {
persistenceService.runInTransaction { ctx ->
ctx.executeNamedUpdate(
SipgateContactSyncDO.DELETE_BY_ADDRESS_ID,
Pair("addressId", addressId),
)
}
}
}
Loading