MerlinExecutionPageRest.ktAnnotations : Valid, RequestBody, GetMapping, PathVariable, Autowired, return, RequestMapping, RestController, PostMapping, RequestParam
Classes : MerlinExecutionPageRest
Supertype(s) : AbstractDynamicPageRest
Fonctions (12) : execute, serialExecution, validate, downloadSerialExecutionTemplate, getForm, createSerialExcelDownloadMenu, createInputElement, hasEditAccess, getUserPref, getFieldId, addUsers, registerColumn
Propriétés (51) : merlinTemplateDao, merlinHandler, merlinRunner, merlinPagesRest, userPrefService, userService, employeeService, executionData, userPref, errors, filename, wordBytes, download, pdfResult, filename, zipFilename, zipByteArray, validationErrors, stats, inputVariables, inputData, filename, excel, logViewerMenuItem, id...
Importations : 30 paquets
Paquet : org.projectforge.plugins.merlin.rest
package org.projectforge.plugins.merlin.rest
import de.micromata.merlin.excel.ExcelSheet
import de.micromata.merlin.word.templating.VariableType
import jakarta.servlet.http.HttpServletRequest
import jakarta.validation.Valid
import mu.KotlinLogging
import org.projectforge.business.fibu.EmployeeService
import org.projectforge.business.user.UserGroupCache
import org.projectforge.business.user.service.UserPrefService
import org.projectforge.business.user.service.UserService
import org.projectforge.common.FormatterUtils
import org.projectforge.framework.i18n.translate
import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext
import org.projectforge.framework.utils.NumberHelper
import org.projectforge.menu.MenuItem
import org.projectforge.menu.MenuItemTargetType
import org.projectforge.plugins.merlin.*
import org.projectforge.rest.admin.LogViewerPageRest
import org.projectforge.rest.config.Rest
import org.projectforge.rest.config.RestUtils
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.ui.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
private val log = KotlinLogging.logger {}
@RestController
@RequestMapping("${Rest.URL}/merlinexecution")
class MerlinExecutionPageRest : AbstractDynamicPageRest() {
@Autowired
private lateinit var merlinTemplateDao: MerlinTemplateDao
@Autowired
private lateinit var merlinHandler: MerlinHandler
@Autowired
private lateinit var merlinRunner: MerlinRunner
@Autowired
private lateinit var merlinPagesRest: MerlinPagesRest
@Autowired
private lateinit var userPrefService: UserPrefService
@Autowired
private lateinit var userService: UserService
@Autowired
private lateinit var employeeService: EmployeeService
/**
* Sera appelé si l'utilisateur souhaite modifier son observeStatus.
*/
@PostMapping("execute")
fun execute(@Valid @RequestBody postData: PostData<MerlinExecutionData>): ResponseEntity<*> {
MerlinPlugin.ensureUserLogSubscription()
val executionData = postData.data
log.info("L'utilisateur souhaite exécuter '${executionData.name}'...")
// Enregistrer les valeurs saisies comme préférence utilisateur :
val userPref = getUserPref(executionData.id)
userPref.inputVariables = executionData.inputVariables
userPref.pdfFormat = executionData.pdfFormat
val errors = validate(executionData)
if (!errors.isNullOrEmpty()) {
return ResponseEntity(ResponseAction(validationErrors = errors), HttpStatus.NOT_ACCEPTABLE)
}
val result = merlinRunner.executeTemplate(executionData.id, executionData.inputVariables)
var filename = result.first
val wordBytes = result.second
var download = wordBytes
if (executionData.pdfFormat) {
try {
val pdfResult = merlinRunner.convertToPdf(wordBytes, filename)
filename = pdfResult.filename
download = pdfResult.content
} catch (ex: Throwable) {
// Un débordement de pile peut se produire.
log.error("Erreur lors de la conversion en pdf (repli vers docx) : ${ex.message}", ex)
}
}
return RestUtils.downloadFile(filename, download)
}
@PostMapping("serialExecution/{id}")
fun serialExecution(
@PathVariable("id", required = true) id: Long,
@RequestParam("file") file: MultipartFile
): ResponseEntity<*> {
MerlinPlugin.ensureUserLogSubscription()
val filename = file.originalFilename
log.info {
"L'utilisateur tente de téléverser un fichier d'exécution en série : id='$id', nom='$filename', taille=${
FormatterUtils.formatBytes(
file.size
)
}."
}
val result = file.inputStream.use { inputStream ->
merlinRunner.serialExecuteTemplate(id, filename ?: "untitled.xlsx", inputStream)
?: throw IllegalArgumentException("Impossible d'exécuter le fichier Excel en série.")
}
val zipFilename = result.first
val zipByteArray = result.second
return RestUtils.downloadFile(zipFilename, zipByteArray)
}
private fun validate(data: MerlinExecutionData): List<ValidationError>? {
val validationErrors = mutableListOf<ValidationError>()
val stats = merlinHandler.analyze(data.id).statistics
// ... (tronqué, total 393 lignes)
868d6abb7 2025 -> 2026 420ce7f24 Correction Merlin pour l'export de la liste des employés pour la fonction en série. bf998d85f BankingServicesRest, DataTransferPublicServicesRest, MerlinExecutionPageRest, ButlerServicet : stream.use (les flux n'étaient pas fermés avant ?) 63081666f En-têtes des fichiers source : 2024 -> 2025. e80642c81 Migration en cours... (tous les tests de tous les paquets : OK).