rajah 9 months ago
commit
4cb46de483
62 changed files with 3464 additions and 0 deletions
  1. 30 0
      .classpath
  2. BIN
      .gradle/8.11.1/checksums/checksums.lock
  3. BIN
      .gradle/8.11.1/executionHistory/executionHistory.bin
  4. BIN
      .gradle/8.11.1/executionHistory/executionHistory.lock
  5. BIN
      .gradle/8.11.1/fileChanges/last-build.bin
  6. BIN
      .gradle/8.11.1/fileHashes/fileHashes.bin
  7. BIN
      .gradle/8.11.1/fileHashes/fileHashes.lock
  8. 0 0
      .gradle/8.11.1/gc.properties
  9. BIN
      .gradle/buildOutputCleanup/buildOutputCleanup.lock
  10. 2 0
      .gradle/buildOutputCleanup/cache.properties
  11. BIN
      .gradle/buildOutputCleanup/outputFiles.bin
  12. BIN
      .gradle/file-system.probe
  13. 0 0
      .gradle/vcs-1/gc.properties
  14. 41 0
      .project
  15. 13 0
      .settings/org.eclipse.buildship.core.prefs
  16. 2 0
      .settings/org.eclipse.core.resources.prefs
  17. 12 0
      .settings/org.eclipse.jdt.core.prefs
  18. 8 0
      .settings/org.eclipse.wst.common.component
  19. 7 0
      .settings/org.eclipse.wst.common.project.facet.core.xml
  20. 2 0
      .settings/org.springframework.ide.eclipse.prefs
  21. 13 0
      bin/main/application.properties
  22. 38 0
      build.gradle
  23. 7 0
      gradle/wrapper/gradle-wrapper.properties
  24. 252 0
      gradlew
  25. 94 0
      gradlew.bat
  26. 1 0
      settings.gradle
  27. 15 0
      src/main/java/fr/triplea/demovote/DemovoteApplication.java
  28. 23 0
      src/main/java/fr/triplea/demovote/persistence/dao/BulletinRepository.java
  29. 23 0
      src/main/java/fr/triplea/demovote/persistence/dao/CategorieRepository.java
  30. 20 0
      src/main/java/fr/triplea/demovote/persistence/dao/MessageRepository.java
  31. 39 0
      src/main/java/fr/triplea/demovote/persistence/dao/ParticipantRepository.java
  32. 21 0
      src/main/java/fr/triplea/demovote/persistence/dao/PreferenceRepository.java
  33. 18 0
      src/main/java/fr/triplea/demovote/persistence/dao/PresentationRepository.java
  34. 27 0
      src/main/java/fr/triplea/demovote/persistence/dao/PrivilegeRepository.java
  35. 27 0
      src/main/java/fr/triplea/demovote/persistence/dao/ProductionRepository.java
  36. 30 0
      src/main/java/fr/triplea/demovote/persistence/dao/RoleRepository.java
  37. 23 0
      src/main/java/fr/triplea/demovote/persistence/dao/VariableRepository.java
  38. 173 0
      src/main/java/fr/triplea/demovote/persistence/model/Bulletin.java
  39. 170 0
      src/main/java/fr/triplea/demovote/persistence/model/Categorie.java
  40. 108 0
      src/main/java/fr/triplea/demovote/persistence/model/Message.java
  41. 384 0
      src/main/java/fr/triplea/demovote/persistence/model/Participant.java
  42. 25 0
      src/main/java/fr/triplea/demovote/persistence/model/ParticipantModePaiement.java
  43. 25 0
      src/main/java/fr/triplea/demovote/persistence/model/ParticipantStatus.java
  44. 111 0
      src/main/java/fr/triplea/demovote/persistence/model/Preference.java
  45. 102 0
      src/main/java/fr/triplea/demovote/persistence/model/Presentation.java
  46. 101 0
      src/main/java/fr/triplea/demovote/persistence/model/Privilege.java
  47. 245 0
      src/main/java/fr/triplea/demovote/persistence/model/Production.java
  48. 25 0
      src/main/java/fr/triplea/demovote/persistence/model/ProductionType.java
  49. 120 0
      src/main/java/fr/triplea/demovote/persistence/model/Role.java
  50. 117 0
      src/main/java/fr/triplea/demovote/persistence/model/Variable.java
  51. 213 0
      src/main/java/fr/triplea/demovote/spring/CreateDefaultValues.java
  52. 32 0
      src/main/java/fr/triplea/demovote/spring/MvcConfig.java
  53. 135 0
      src/main/java/fr/triplea/demovote/web/controller/BulletinController.java
  54. 101 0
      src/main/java/fr/triplea/demovote/web/controller/CategorieController.java
  55. 33 0
      src/main/java/fr/triplea/demovote/web/controller/MessageController.java
  56. 126 0
      src/main/java/fr/triplea/demovote/web/controller/ParticipantController.java
  57. 65 0
      src/main/java/fr/triplea/demovote/web/controller/PreferenceController.java
  58. 32 0
      src/main/java/fr/triplea/demovote/web/controller/PresentationController.java
  59. 117 0
      src/main/java/fr/triplea/demovote/web/controller/ProductionController.java
  60. 90 0
      src/main/java/fr/triplea/demovote/web/controller/VariableController.java
  61. 13 0
      src/main/resources/application.properties
  62. 13 0
      src/test/java/fr/triplea/demovote/DemovoteApplicationTests.java

+ 30 - 0
.classpath

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="bin/main" path="src/main/java">
+		<attributes>
+			<attribute name="gradle_scope" value="main"/>
+			<attribute name="gradle_used_by_scope" value="main,test"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="bin/main" path="src/main/resources">
+		<attributes>
+			<attribute name="gradle_scope" value="main"/>
+			<attribute name="gradle_used_by_scope" value="main,test"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="bin/test" path="src/test/java">
+		<attributes>
+			<attribute name="gradle_scope" value="test"/>
+			<attribute name="gradle_used_by_scope" value="test"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
+	<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
+	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
+		<attributes>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin/default"/>
+</classpath>

BIN
.gradle/8.11.1/checksums/checksums.lock


BIN
.gradle/8.11.1/executionHistory/executionHistory.bin


BIN
.gradle/8.11.1/executionHistory/executionHistory.lock


BIN
.gradle/8.11.1/fileChanges/last-build.bin


BIN
.gradle/8.11.1/fileHashes/fileHashes.bin


BIN
.gradle/8.11.1/fileHashes/fileHashes.lock


+ 0 - 0
.gradle/8.11.1/gc.properties


BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock


+ 2 - 0
.gradle/buildOutputCleanup/cache.properties

@@ -0,0 +1,2 @@
+#Tue Feb 18 10:41:17 CET 2025
+gradle.version=8.11.1

BIN
.gradle/buildOutputCleanup/outputFiles.bin


BIN
.gradle/file-system.probe


+ 0 - 0
.gradle/vcs-1/gc.properties


+ 41 - 0
.project

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>demovote-backend</name>
+	<comment>Project demovote-backend created by Buildship.</comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
+	</natures>
+</projectDescription>

+ 13 - 0
.settings/org.eclipse.buildship.core.prefs

@@ -0,0 +1,13 @@
+arguments=
+auto.sync=false
+build.scans.enabled=false
+connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
+connection.project.dir=
+eclipse.preferences.version=1
+gradle.user.home=
+java.home=
+jvm.arguments=
+offline.mode=false
+override.workspace.settings=false
+show.console.view=false
+show.executions.view=false

+ 2 - 0
.settings/org.eclipse.core.resources.prefs

@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8

+ 12 - 0
.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=17

+ 8 - 0
.settings/org.eclipse.wst.common.component

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-modules id="moduleCoreId" project-version="1.5.0">
+	<wb-module deploy-name="demovote-backend">
+		<property name="context-root" value="demovote-backend"/>
+		<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/>
+		<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
+	</wb-module>
+</project-modules>

+ 7 - 0
.settings/org.eclipse.wst.common.project.facet.core.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+	<fixed facet="jst.java"/>
+	<fixed facet="jst.web"/>
+	<installed facet="jst.web" version="2.4"/>
+	<installed facet="jst.java" version="17"/>
+</faceted-project>

+ 2 - 0
.settings/org.springframework.ide.eclipse.prefs

@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1

+ 13 - 0
bin/main/application.properties

@@ -0,0 +1,13 @@
+spring.application.name=demovote-backend
+
+spring.datasource.url=jdbc:postgresql://localhost:5432/vote
+spring.datasource.username=vote
+spring.datasource.password=Atari$Impact2024
+spring.jpa.hibernate.ddl-auto=validate
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+
+#spring.jpa.show-sql=true
+
+logging.level.org.springframework=INFO
+
+server.servlet.context-path=/

+ 38 - 0
build.gradle

@@ -0,0 +1,38 @@
+plugins {
+	id 'java'
+	id 'war'
+	id 'org.springframework.boot' version '3.4.2'
+	id 'io.spring.dependency-management' version '1.1.7'
+}
+
+group = 'fr.triplea'
+version = '0.0.1-SNAPSHOT'
+
+java { toolchain { languageVersion = JavaLanguageVersion.of(17) } }
+
+repositories { mavenCentral() }
+
+dependencies {
+	
+	developmentOnly 'org.springframework.boot:spring-boot-devtools'
+
+  implementation 'org.springframework.boot:spring-boot-starter-actuator'
+  implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+  implementation 'org.springframework.boot:spring-boot-starter-web'
+
+  implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0'
+  implementation 'org.hibernate.validator:hibernate-validator:8.0.2.Final'
+	
+  runtimeOnly 'org.postgresql:postgresql'
+
+  providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
+	
+  testImplementation 'org.springframework.boot:spring-boot-starter-test'
+
+  testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+}
+
+
+tasks.named('test') { useJUnitPlatform() }
+
+tasks.withType(JavaCompile).configureEach { options.compilerArgs.add("-parameters") }

+ 7 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 252 - 0
gradlew

@@ -0,0 +1,252 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 94 - 0
gradlew.bat

@@ -0,0 +1,94 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 1 - 0
settings.gradle

@@ -0,0 +1 @@
+rootProject.name = 'demovote-backend'

+ 15 - 0
src/main/java/fr/triplea/demovote/DemovoteApplication.java

@@ -0,0 +1,15 @@
+package fr.triplea.demovote;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(exclude = {
+    org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
+    org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class}
+    )
+public class DemovoteApplication 
+{
+
+	public static void main(String[] args) { SpringApplication.run(DemovoteApplication.class, args); }
+
+}

+ 23 - 0
src/main/java/fr/triplea/demovote/persistence/dao/BulletinRepository.java

@@ -0,0 +1,23 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Bulletin;
+
+public interface BulletinRepository extends JpaRepository<Bulletin, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT u.* FROM vote.bulletins AS u WHERE u.numero_categorie = :categorie AND u.numero_participant = :participant ")
+  Bulletin findByCategorieAndParticipant(@Param("categorie") int cat_id, @Param("participant") int part_id);
+  
+  @NativeQuery("SELECT DISTINCT u.* FROM vote.bulletins AS u WHERE u.numero_categorie = :categorie ")
+  List<Bulletin> findByCategorie(@Param("categorie") int cat_id);
+
+  @NativeQuery("SELECT DISTINCT u.* FROM vote.bulletins AS u WHERE u.numero_participant = :participant ")
+  List<Bulletin> findByParticipant(@Param("participant") int part_id);
+
+}

+ 23 - 0
src/main/java/fr/triplea/demovote/persistence/dao/CategorieRepository.java

@@ -0,0 +1,23 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Categorie;
+
+public interface CategorieRepository extends JpaRepository<Categorie, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT c.* FROM vote.categories AS c WHERE c.numero_categorie = :id AND c.flag_actif IS TRUE ")
+  Categorie findById(@Param("id") int id);
+  
+  @NativeQuery("SELECT DISTINCT c.* FROM vote.categories AS c WHERE c.flag_actif IS TRUE ORDER BY c.numero_ordre ASC ")
+  List<Categorie> findAll();
+
+  @Override
+  void delete(Categorie categorie);
+
+}

+ 20 - 0
src/main/java/fr/triplea/demovote/persistence/dao/MessageRepository.java

@@ -0,0 +1,20 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Message;
+
+public interface MessageRepository extends JpaRepository<Message, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT m.* FROM vote.messages AS m WHERE m.numero_mesage = :id ")
+  Message findById(@Param("id") int id);
+
+  @NativeQuery("SELECT DISTINCT m.* FROM vote.messages AS m WHERE m.numero_destinataire = :destinataire OR m.numero_participant = :participant OR m.numero_destinataire IS NULL ORDER BY m.date_creation DESC ")
+  List<Message> findAll(@Param("participant") int participant, @Param("destinataire") int destinataire);
+  
+}

+ 39 - 0
src/main/java/fr/triplea/demovote/persistence/dao/ParticipantRepository.java

@@ -0,0 +1,39 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Participant;
+import fr.triplea.demovote.persistence.model.Role;
+
+public interface ParticipantRepository extends JpaRepository<Participant, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.participants AS p WHERE p.numero_participant = :id AND p.flag_actif IS TRUE ")
+  Participant findById(@Param("id") int id);
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.participants AS p WHERE p.flag_actif IS TRUE ORDER BY p.nom ASC, p.prenom ASC, p.pseudonyme ASC ")
+  List<Participant> findAll();
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.participants_roles AS rp INNER JOIN vote.participants AS p ON rp.numero_participant = p.numero_participant INNER JOIN vote.roles AS r ON rp.numero_role = r.numero_role WHERE p.flag_actif IS TRUE AND r.flag_actif IS TRUE AND rp.numero_role = :role ORDER BY p.nom ASC, p.prenom ASC, p.pseudonyme ASC ")
+  List<Participant> findByRole(@Param("role") Role role);
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.participants AS p WHERE p.flag_actif IS TRUE AND p.pseudonyme = :pseudo ORDER BY p.nom ASC, p.prenom ASC, p.pseudonyme ASC ")
+  Participant findByPseudonyme(@Param("pseudo") String pseudonyme);
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.participants AS p WHERE p.status = :status AND p.flag_actif IS TRUE ORDER BY p.nom ASC, p.prenom ASC, p.pseudonyme ASC ")
+  List<Participant> findByStatus(@Param("status") String status);
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.participants AS p WHERE p.flag_arrive = :arrive AND p.flag_actif IS TRUE ORDER BY p.nom ASC, p.prenom ASC, p.pseudonyme ASC ")
+  List<Participant> findByArrived(@Param("arrive") boolean flag_arrive);
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.participants AS p WHERE p.flag_dodo_sur_place = :dodo AND p.flag_actif IS TRUE ORDER BYp.nom ASC, p.prenom ASC, p.pseudonyme ASC ")
+  List<Participant> findBySleepingOnSite(@Param("dodo") boolean flag_dodo_sur_place);
+
+  @Override
+  void delete(Participant participant);
+
+}

+ 21 - 0
src/main/java/fr/triplea/demovote/persistence/dao/PreferenceRepository.java

@@ -0,0 +1,21 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Participant;
+import fr.triplea.demovote.persistence.model.Preference;
+
+public interface PreferenceRepository extends JpaRepository<Preference, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.preferences AS p WHERE p.numero_preference = :id ")
+  Preference findById(@Param("id") int id);
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.preferences AS p WHERE p.numero_participant = :participant AND p.numero_traitement = :traitement ")
+  List<Preference> findByParticipantAndTraitement(@Param("participant") Participant participant, @Param("numTtt") int traitement);
+
+}

+ 18 - 0
src/main/java/fr/triplea/demovote/persistence/dao/PresentationRepository.java

@@ -0,0 +1,18 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Categorie;
+import fr.triplea.demovote.persistence.model.Presentation;
+
+public interface PresentationRepository extends JpaRepository<Presentation, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.presentations AS p WHERE p.numero_categorie = :categorie ")
+  List<Presentation> findByCategorie(@Param("categorie") Categorie categorie);
+
+}

+ 27 - 0
src/main/java/fr/triplea/demovote/persistence/dao/PrivilegeRepository.java

@@ -0,0 +1,27 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Privilege;
+import fr.triplea.demovote.persistence.model.Role;
+
+public interface PrivilegeRepository extends JpaRepository<Privilege, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.privileges AS p WHERE p.numero_privilege = :id ")
+  Privilege findById(@Param("id") int id);
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.privileges AS p WHERE p.libelle = :libelle ")
+  Privilege findByLibelle(@Param("libelle") String libelle);
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.roles_privileges AS rp INNER JOIN vote.roles AS r ON rp.numero_role = r.numero_role INNER JOIN vote.privileges AS p ON rp.numero_privilege = r.numero_privilege WHERE r.flag_actif IS TRUE AND r.numero_role = :role ")
+  List<Privilege> findbyRole(@Param("role") Role role);
+
+  @Override
+  void delete(Privilege privilege);
+  
+}

+ 27 - 0
src/main/java/fr/triplea/demovote/persistence/dao/ProductionRepository.java

@@ -0,0 +1,27 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Participant;
+import fr.triplea.demovote.persistence.model.Production;
+
+public interface ProductionRepository extends JpaRepository<Production, Integer> 
+{
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.productions AS p WHERE p.numero_production = :id p.flag_actif IS TRUE ")
+  Production findById(@Param("id") int id);
+  
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.productions AS p WHERE p.flag_actif IS TRUE ORDER BY p.titre ASC ")
+  List<Production> findAll();
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.productions AS p WHERE p.numero_participant = :participant AND p.flag_actif IS TRUE ")
+  List<Production> findByParticipant(@Param("participant") Participant participant);
+
+  @Override
+  void delete(Production production);
+  
+}

+ 30 - 0
src/main/java/fr/triplea/demovote/persistence/dao/RoleRepository.java

@@ -0,0 +1,30 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Privilege;
+import fr.triplea.demovote.persistence.model.Role;
+
+public interface RoleRepository extends JpaRepository<Role, Integer> 
+{
+
+  @NativeQuery("SELECT DISTINCT r.* FROM vote.roles AS r WHERE r.numero_role = :id AND r.flag_actif IS TRUE ")
+  Role findById(@Param("id") int id);
+  
+  @NativeQuery("SELECT DISTINCT r.* FROM vote.roles AS r WHERE r.libelle = :libelle AND  r.flag_actif IS TRUE ")
+  Role findByLibelle(@Param("libelle") String libelle);
+  
+  @NativeQuery("SELECT DISTINCT r.* FROM vote.roles AS r WHERE r.flag_actif IS TRUE ")
+  List<Role> findAll();
+  
+  @NativeQuery("SELECT DISTINCT r.* FROM vote.roles_privileges AS rp INNER JOIN vote.roles AS r ON rp.numero_role = r.numero_role INNER JOIN vote.privileges AS p ON rp.numero_privilege = r.numero_privilege WHERE r.flag_actif IS TRUE AND p.numero_privilege = :privilege ")
+  List<Role> findbyPrivilege(@Param("privilege") Privilege privilege);
+
+  @Override
+  void delete(Role role);
+
+}

+ 23 - 0
src/main/java/fr/triplea/demovote/persistence/dao/VariableRepository.java

@@ -0,0 +1,23 @@
+package fr.triplea.demovote.persistence.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.NativeQuery;
+import org.springframework.data.repository.query.Param;
+
+import fr.triplea.demovote.persistence.model.Variable;
+
+public interface VariableRepository extends JpaRepository<Variable, Integer> 
+{
+  
+  @NativeQuery("SELECT DISTINCT v.* FROM vote.variables AS v WHERE v.numero_variable = :id ")
+  Variable findById(@Param("id") int id);
+
+  @NativeQuery("SELECT DISTINCT v.* FROM vote.variables AS v WHERE v.type = :type ORDER BY v.type ASC, v.code ASC ")
+  List<Variable> findByType(@Param("type") String type);
+
+  @NativeQuery("SELECT DISTINCT v.* FROM vote.variables AS v WHERE v.type = :type AND v.code = :code ")
+  Variable findByTypeAndCode(@Param("type") String type, @Param("code") String code);
+
+}

+ 173 - 0
src/main/java/fr/triplea/demovote/persistence/model/Bulletin.java

@@ -0,0 +1,173 @@
+package fr.triplea.demovote.persistence.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import jakarta.persistence.UniqueConstraint;
+
+@Entity(name = "vote.bulletins")
+@Table(name = "bulletins", uniqueConstraints = { @UniqueConstraint(columnNames = { "numero_categorie", "numero_participant" }) })
+public class Bulletin
+{
+  
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_bulletin")
+  private Integer numeroBulletin;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_categorie", referencedColumnName="numero_categorie")
+  private Categorie categorie;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_participant", referencedColumnName="numero_participant")
+  private Participant participant;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "numero_production01", referencedColumnName="numero_production")
+  private Production production01;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production02", referencedColumnName="numero_production")
+  private Production production02;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production03", referencedColumnName="numero_production")
+  private Production production03;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production04", referencedColumnName="numero_production")
+  private Production production04;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production05", referencedColumnName="numero_production")
+  private Production production05;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production06", referencedColumnName="numero_production")
+  private Production production06;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production07", referencedColumnName="numero_production")
+  private Production production07;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production08", referencedColumnName="numero_production")
+  private Production production08;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production09", referencedColumnName="numero_production")
+  private Production production09;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_production10", referencedColumnName="numero_production")
+  private Production production10;
+ 
+  @Column(name = "flag_valide")
+  private Boolean confirmed = false;
+  
+  
+  public Bulletin() { super(); }
+ 
+  
+  public Integer getNumeroBulletin() { return this.numeroBulletin; }
+
+  public void setCategorie(Categorie c) { this.categorie = c; }
+  public Categorie getCategorie() { return this.categorie; }
+
+  public void setParticipant(Participant p) { this.participant = p; }
+  public Participant getParticipant() { return this.participant; }
+  
+  public void setProduction01(Production p) { this.production01 = p; }
+  public Production getProduction01() { return this.production01; }
+  
+  public void setProduction02(Production p) { this.production02 = p; }
+  public Production getProduction02() { return this.production02; }
+  
+  public void setProduction03(Production p) { this.production03 = p; }
+  public Production getProduction03() { return this.production03; }
+  
+  public void setProduction04(Production p) { this.production04 = p; }
+  public Production getProduction04() { return this.production04; }
+  
+  public void setProduction05(Production p) { this.production05 = p; }
+  public Production getProduction05() { return this.production05; }
+  
+  public void setProduction06(Production p) { this.production06 = p; }
+  public Production getProduction06() { return this.production06; }
+  
+  public void setProduction07(Production p) { this.production07 = p; }
+  public Production getProduction07() { return this.production07; }
+  
+  public void setProduction08(Production p) { this.production08 = p; }
+  public Production getProduction08() { return this.production08; }
+  
+  public void setProduction09(Production p) { this.production09 = p; }
+  public Production getProduction09() { return this.production09; }
+  
+  public void setProduction10(Production p) { this.production10 = p; }
+  public Production getProduction10() { return this.production10; }
+  
+  public void setConfirmed(boolean b) { this.confirmed = b; }
+  public Boolean getConfirmed() { return this.confirmed; }
+  public boolean isConfirmed() { return (getConfirmed().booleanValue()); }
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getNumeroBulletin() == null) ? 0 : getNumeroBulletin().hashCode());
+    result = (prime * result) + ((getCategorie() == null) ? 0 : getCategorie().hashCode());
+    result = (prime * result) + ((getParticipant() == null) ? 0 : getParticipant().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Bulletin b = (Bulletin) obj;
+    if (getNumeroBulletin() == null) { if (b.getNumeroBulletin() == null) { return false; } } else if (!getNumeroBulletin().equals(b.getNumeroBulletin())) { return false; }
+    if (getCategorie() == null) { if (b.getCategorie() == null) { return false; } } else if (!getCategorie().equals(b.getCategorie())) { return false; }
+    if (getParticipant() == null) { if (b.getParticipant() == null) { return false; } } else if (!getParticipant().equals(b.getParticipant())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Bulletin [id=")
+           .append(numeroBulletin)
+           .append(", categorie=").append(categorie)
+           .append(", participant=").append(participant)
+           .append(confirmed ? ", confirmé" : "")
+           .append(", production01=").append(production01)
+           .append(", production02=").append(production02)
+           .append(", production03=").append(production03)
+           .append(", production03=").append(production04)
+           .append(", production05=").append(production05)
+           .append(", production06=").append(production06)
+           .append(", production07=").append(production07)
+           .append(", production08=").append(production08)
+           .append(", production09=").append(production09)
+           .append(", production10=").append(production10)
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 170 - 0
src/main/java/fr/triplea/demovote/persistence/model/Categorie.java

@@ -0,0 +1,170 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.util.StringUtils;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+import jakarta.persistence.Transient;
+
+
+@Entity(name = "vote.categories")
+@Table(name = "categories")
+public class Categorie
+{
+   
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @UpdateTimestamp
+  private LocalDateTime dateModification;
+  
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_categorie")
+  private Integer numeroCategorie;
+
+  @Column(name = "flag_actif")
+  private Boolean enabled = true;
+
+  @Column(length = 128, nullable = false)
+  private String libelle;
+  
+  private Integer numeroOrdre = 1;
+
+  @Column(name = "flag_affiche")
+  private Boolean available = false;
+
+  @Column(name = "flag_upload")
+  private Boolean uploadable = true;
+ 
+  @Column(name = "flag_vote_ouvert")
+  private Boolean pollable = false;
+
+  @Column(name = "flag_calcul")
+  private Boolean computed = false;
+  
+  private Integer nombreVotants = 0;
+
+  @Column(name = "flag_diaporama")
+  private Boolean displayable = false;
+  
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "categorie")
+  private List<Presentation> presentations;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "categorie")
+  private List<Bulletin> bulletins;
+  
+  
+  public Categorie() { super(); }
+
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+  
+  public LocalDateTime getDateModification() { return this.dateModification; }
+  
+  public Integer getNumeroCategorie() { return this.numeroCategorie; }
+  
+  public void setEnabled(boolean b) { this.enabled = Boolean.valueOf(b); }
+  public Boolean getEnabled() { return this.enabled; }
+  public boolean isEnabled() { return (getEnabled().booleanValue()); }
+  
+  public void setLibelle(String str) { if (str != null) { this.libelle = StringUtils.truncate(str, 128); } }
+  public String getLibelle() { return this.libelle; }
+  
+  public void setNumeroOrdre(int o) { this.numeroOrdre = Integer.valueOf(o); }
+  public Integer getNumeroOrdre() { return this.numeroOrdre; }
+  
+  public void setAvaiable(boolean b) { this.available = Boolean.valueOf(b); }
+  public Boolean getAvailable() { return this.available; }
+  @Transient
+  public boolean isAvailable() { return (getAvailable().booleanValue()); }
+  
+  public void setUploadable(boolean b) { this.uploadable = Boolean.valueOf(b); }
+  public Boolean getUploadable() { return this.uploadable; }
+  @Transient
+  public boolean isUploadable() { return (getUploadable().booleanValue()); }
+  
+  public void setPollable(boolean b) { this.pollable = Boolean.valueOf(b); }
+  public Boolean getPollable() { return this.pollable; }
+  @Transient
+  public boolean isPollable() { return (getPollable().booleanValue()); }
+  
+  public void setComputed(boolean b) { this.computed = Boolean.valueOf(b); }
+  public Boolean getComputed() { return this.computed; }
+  @Transient
+  public boolean isComputed() { return (getComputed().booleanValue()); }
+  
+  public void setNombreVotants(int n) { this.nombreVotants = Integer.valueOf(n); }
+  public Integer getNombreVotants() { return this.nombreVotants; }
+  
+  public void setDisplayable(boolean b) { this.displayable = Boolean.valueOf(b); }
+  public Boolean getDisplayable() { return this.displayable; }
+  @Transient
+  public boolean isDisplayable() { return (getDisplayable().booleanValue()); }
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getNumeroCategorie() == null) ? 0 : getNumeroCategorie().hashCode());
+    result = (prime * result) + ((getLibelle() == null) ? 0 : getLibelle().hashCode());
+    result = (prime * result) + ((getEnabled() == null) ? 0 : getEnabled().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Categorie c = (Categorie) obj;
+    if (getNumeroCategorie() == null) { if (c.getNumeroCategorie() == null) { return false; } } else if (!getNumeroCategorie().equals(c.getNumeroCategorie())) { return false; }
+    if (getLibelle() == null) { if (c.getLibelle() == null) { return false; } } else if (!getLibelle().equals(c.getLibelle())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Categorie [id=")
+           .append(numeroCategorie)
+           .append(", libelle=").append(libelle)
+           .append(", numeroOrdre=").append(numeroOrdre)
+           .append(available ? ", accessible" : "")
+           .append(uploadable ? ", fichiers téléversables" : "")
+           .append(pollable ? ", vote ouvert" : "")
+           .append(computed ? ", vote calculé" : "")
+           .append(", nombre votants=").append(nombreVotants)
+           .append(displayable ? ", diaporama" : "")
+           .append(", créé=").append(dateCreation)
+           .append(", modifié=").append(dateModification)
+           .append(enabled ? "" : ", inactif")
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 108 - 0
src/main/java/fr/triplea/demovote/persistence/model/Message.java

@@ -0,0 +1,108 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.time.LocalDateTime;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.springframework.util.StringUtils;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+
+@Entity(name = "vote.messages")
+@Table(name = "messages")
+public class Message
+{
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_message")
+  private Integer numeroMessage;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_participant", referencedColumnName="numero_participant")
+  private Participant participant;
+  
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name="numero_destinataire", referencedColumnName="numero_participant")
+  private Participant destinataire;
+
+  @Column(length = 4000, nullable = false)
+  private String ligne;
+
+  
+  public Message() { super(); }
+
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+  
+  public Integer getNumeroMessage() { return this.numeroMessage; }
+  
+  public void setParticipant(Participant p) { this.participant = p; }
+  public Participant getParticipant() { return this.participant; }
+
+  public void setDestinataire(Participant d) { this.destinataire = d; }
+  public Participant getDestinataire() { return this.destinataire; }
+
+  public void setLigne(String str) { if (str != null) { this.ligne = StringUtils.truncate(str, 4000); } }
+  public String getLigne() { return this.ligne; }
+
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getNumeroMessage() == null) ? 0 : getNumeroMessage().hashCode());
+    result = (prime * result) + ((getParticipant() == null) ? 0 : getParticipant().hashCode());
+    result = (prime * result) + ((getDestinataire() == null) ? 0 : getDestinataire().hashCode());
+    result = (prime * result) + ((getLigne() == null) ? 0 : getLigne().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Message m = (Message) obj;
+    if (getNumeroMessage() == null) { if (m.getNumeroMessage() == null) { return false; } } else if (!getNumeroMessage().equals(m.getNumeroMessage())) { return false; }
+    if (getParticipant() == null) { if (m.getParticipant() == null) { return false; } } else if (!getParticipant().equals(m.getParticipant())) { return false; }
+    if (getDestinataire() == null) { if (m.getDestinataire() == null) { return false; } } else if (!getDestinataire().equals(m.getDestinataire())) { return false; }
+    if (getLigne() == null) { if (m.getLigne() == null) { return false; } } else if (!getLigne().equals(m.getLigne())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Message [id=")
+           .append(numeroMessage)
+           .append(", participant=").append(participant)
+           .append(", destinataire=").append(destinataire)
+           .append(", ligne=").append(ligne)
+           .append(", créé=").append(dateCreation)
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 384 - 0
src/main/java/fr/triplea/demovote/persistence/model/Participant.java

@@ -0,0 +1,384 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.util.StringUtils;
+
+import com.google.common.collect.Sets;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.JoinTable;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+import jakarta.persistence.Transient;
+
+@Entity(name = "vote.participants")
+@Table(name = "participants")
+public class Participant
+{
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @UpdateTimestamp
+  private LocalDateTime dateModification;
+
+  @ManyToMany(fetch = FetchType.EAGER)
+  @JoinTable(name = "participants_roles", 
+             joinColumns = @JoinColumn(name = "numero_participant", referencedColumnName = "numero_participant"), 
+             inverseJoinColumns = @JoinColumn(name = "numero_role", referencedColumnName = "numero_role"))
+  private List<Role> roles;
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_participant")
+  private Integer numeroParticipant;
+
+  @Column(name = "flag_actif")
+  private Boolean enabled = true;
+
+  @Column(length = 128, nullable = false)
+  private String nom;
+
+  @Column(length = 128)
+  private String prenom;
+
+  @Column(length = 128, unique = true, nullable = false)
+  private String pseudonyme;
+
+  @Column(length = 128)
+  private String groupe;
+
+  @Column(length = 256)
+  private String motDePasse;
+
+  @Column(name = "flag_expire")
+  private Boolean passwordExpired = false;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  private LocalDateTime dateExpiration;
+  
+  private Integer delaiDeconnexion = 15;
+
+  @Column(length = 256)
+  private String adresse;
+
+  @Column(length = 16)
+  private String codePostal;
+
+  @Column(length = 128)
+  private String ville;
+
+  @Column(length = 128)
+  private String pays;
+
+  @Column(length = 32)
+  private String numeroTelephone;
+
+  @Column(length = 128)
+  private String email;
+
+  @Enumerated(EnumType.STRING) 
+  private ParticipantStatus status;
+
+  @Column(name = "flag_machine")
+  private Boolean withMachine = true;
+
+  private String commentaire;
+
+  @Column(name = "flag_jour1")
+  private Boolean hereDay1 = false;
+
+  @Column(name = "flag_jour2")
+  private Boolean hereDay2 = false;
+
+  @Column(name = "flag_jour3")
+  private Boolean hereDay3 = false;
+
+  @Column(name = "flag_dodo_sur_place")
+  private Boolean sleepingOnSite = true;
+
+  @Column(name = "flag_amigabus")
+  private Boolean useAmigabus = false;
+
+  @Enumerated(EnumType.STRING) 
+  private ParticipantModePaiement modePaiement;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  private LocalDateTime dateInscription;
+  
+  @Column(precision=10, scale=2)
+  private BigDecimal sommeRecue = BigDecimal.ZERO;
+
+  @Column(name = "flag_arrive")
+  private Boolean arrived = false;
+  
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "participant")
+  private List<Preference> preferences;
+  
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "participant")
+  private List<Production> productions;
+  
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "participant")
+  private List<Bulletin> bulletins;
+  
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "participant")
+  private List<Message> messagesParticpant;
+  
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "destinataire")
+  private List<Message> messagesDestinataire;
+
+  
+  public Participant() { super(); }
+
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+  
+  public LocalDateTime getDateModification() { return this.dateModification; }
+  
+  public List<Role> getRoles() { return roles; }
+  public void setRoles(final List<Role> roles) { this.roles = roles; }
+  
+  public Integer getNumeroParticipant() { return this.numeroParticipant; }
+  
+  public void setEnabled(boolean b) { this.enabled = Boolean.valueOf(b); }
+  public Boolean getEnabled() { return this.enabled; }
+  @Transient
+  public boolean isEnabled() { return (getEnabled().booleanValue()); }
+  
+  public void setNom(String str) { if (str != null) { this.nom = StringUtils.truncate(str, 128); } }
+  public String getNom() { return this.nom; }
+  
+  public void setPrenom(String str) { if (str != null) { this.prenom = StringUtils.truncate(str, 128); } }
+  public String getPrenom() { return this.prenom; }
+  
+  public void setPseudonyme(String str) { if (str != null) { this.pseudonyme = StringUtils.truncate(str, 128); } }
+  public String getPseudonyme() { return this.pseudonyme; }
+  
+  public void setGroupe(String str) { if (str != null) { this.groupe = StringUtils.truncate(str, 128); } }
+  public String getGroupe() { return this.groupe; }
+  
+  public void setMotDePasse(String str) { if (str != null) { this.motDePasse = StringUtils.truncate(str, 256); } }
+  public String getMotDePasse() { return this.motDePasse; }
+  
+  public void setPasswordExpired(boolean b) { this.passwordExpired = Boolean.valueOf(b); }
+  public Boolean getPasswordExpired() { return this.passwordExpired; }
+  @Transient
+  public boolean isPasswordExpired() { return (getPasswordExpired().booleanValue()); }
+  
+  public void setDateExpiration(LocalDateTime d) { this.dateExpiration = d; }
+  public LocalDateTime getDateExpiration() { return this.dateExpiration; }
+  
+  public void setDelaiDeconnexion(int n) { this.delaiDeconnexion = Integer.valueOf(n); }
+  public Integer getDelaiDeconnexion() { return this.delaiDeconnexion; }
+  
+  public void setAdresse(String str) { if (str != null) { this.adresse = StringUtils.truncate(str, 256); } }
+  public String getAdresse() { return this.adresse; }
+  
+  public void setCodePostal(String str) { if (str != null) { this.codePostal = StringUtils.truncate(str, 16); } }
+  public String getCodePostal() { return this.codePostal; }
+  
+  public void setVille(String str) { if (str != null) { this.ville = StringUtils.truncate(str, 128); } }
+  public String getVille() { return this.ville; }
+  
+  public void setPays(String str) { if (str != null) { this.pays = StringUtils.truncate(str, 128); } }
+  public String getPays() { return this.pays; }
+  
+  public void setNumeroTelephone(String str) { if (str != null) { this.numeroTelephone = StringUtils.truncate(str, 32); } }
+  public String getNumeroTelephone() { return this.numeroTelephone; }
+  
+  public void setEmail(String str) { if (str != null) { this.email = StringUtils.truncate(str, 128); } }
+  public String getEmail() { return this.email; }
+  
+  public void setStatus(ParticipantStatus enu) { this.status = enu; }
+  public ParticipantStatus getStatus() { return this.status; }
+  
+  public void setWithMachine(boolean b) { this.withMachine = Boolean.valueOf(b); }
+  public Boolean getWithMachine() { return this.withMachine; }
+  @Transient
+  public boolean isWithMachine() { return (getWithMachine().booleanValue()); }
+  
+  public void setCommentaire(String str) { this.commentaire = new String(str); }
+  public String getCommentaire() { return this.commentaire; }
+  
+  public void setHereDay1(boolean b) { this.hereDay1 = Boolean.valueOf(b); }
+  public Boolean getHereDay1() { return this.hereDay1; }
+  @Transient
+  public boolean isHereDay1() { return (getHereDay1().booleanValue()); }
+  
+  public void setHereDay2(boolean b) { this.hereDay2 = Boolean.valueOf(b); }
+  public Boolean getHereDay2() { return this.hereDay2; }
+  @Transient
+  public boolean isHereDay2() { return (getHereDay2().booleanValue()); }
+  
+  public void setHereDay3(boolean b) { this.hereDay3 = Boolean.valueOf(b); }
+  public Boolean getHereDay3() { return this.hereDay3; }
+  @Transient
+  public boolean isHereDay3() { return (getHereDay3().booleanValue()); }
+  
+  public void setSleepingOnSite(boolean b) { this.sleepingOnSite = Boolean.valueOf(b); }
+  public Boolean getSleepingOnSite() { return this.sleepingOnSite; }
+  @Transient
+  public boolean isSleepingOnSite() { return (getSleepingOnSite().booleanValue()); }
+  
+  public void setUseAmigabus(boolean b) { this.useAmigabus = Boolean.valueOf(b); }
+  public Boolean getUseAmigabus() { return this.useAmigabus; }
+  @Transient
+  public boolean isUseAmigabus() { return (getUseAmigabus().booleanValue()); }
+  
+  public void setModePaiement(ParticipantModePaiement enu) { this.modePaiement = enu; }
+  public ParticipantModePaiement getModePaiement() { return this.modePaiement; }
+  
+  public void setDateInscription(LocalDateTime d) { this.dateInscription = d; }
+  public LocalDateTime getDateInscription() { return this.dateInscription; }
+  
+  public void setSommeRecue(BigDecimal d) { this.sommeRecue = d; }
+  public BigDecimal getSommeRecue() { return this.sommeRecue; }
+  
+  public void setArrived(boolean b) { this.arrived = Boolean.valueOf(b); }
+  public Boolean getArrived() { return this.arrived; }
+  @Transient
+  public boolean isArrived() { return (getArrived().booleanValue()); }
+  
+  
+  @Transient
+  public boolean hasAnyRoles(String... roles) { return hasAnyRoles(Arrays.asList(roles)); }
+
+  @Transient
+  public boolean hasAnyRoles(List<String> roles) 
+  {
+    Set<String> _roles = this.getRoles().stream().map(Role::getLibelle).collect(Collectors.toSet());
+      
+    Sets.SetView<String> intersection = Sets.intersection(Sets.newHashSet(roles), _roles);
+      
+    return !intersection.isEmpty();
+  }
+
+  @Transient
+  public boolean hasRoles(String... roles) { return hasRoles(Arrays.asList(roles)); }
+
+  @Transient
+  public boolean hasRoles(List<String> roles) 
+  {
+    Set<String> _roles = this.getRoles().stream().map(Role::getLibelle).collect(Collectors.toSet());
+      
+    return _roles.containsAll(roles);
+  }
+
+  @Transient
+  public boolean hasAnyPrivileges(String... privileges) { return hasAnyPrivileges(Arrays.asList(privileges)); }
+
+  @Transient
+  public boolean hasAnyPrivileges(List<String> privileges) 
+  {
+    Set<String> _privileges = this.getRoles().stream().flatMap(s -> s.getPrivileges().stream()).map(Privilege::getLibelle).collect(Collectors.toSet());
+      
+    Sets.SetView<String> intersection = Sets.intersection(_privileges, Sets.newHashSet(privileges));
+    
+    return !intersection.isEmpty();
+  }
+
+  @Transient
+  public boolean hasPrivileges(String... privileges) { return hasPrivileges(Arrays.asList(privileges)); }
+
+  @Transient
+  public boolean hasPrivileges(List<String> privileges) 
+  {
+    Set<String> _privileges = this.getRoles().stream().flatMap(s -> s.getPrivileges().stream()).map(Privilege::getLibelle).collect(Collectors.toSet());
+    
+    return _privileges.containsAll(privileges);
+  }
+
+  
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getNumeroParticipant() == null) ? 0 : getNumeroParticipant().hashCode());
+    result = (prime * result) + ((getEnabled() == null) ? 0 : getEnabled().hashCode());
+    result = (prime * result) + ((getNom() == null) ? 0 : getNom().hashCode());
+    result = (prime * result) + ((getPrenom() == null) ? 0 : getPrenom().hashCode());
+    result = (prime * result) + ((getPseudonyme() == null) ? 0 : getPseudonyme().hashCode());
+    result = (prime * result) + ((getGroupe() == null) ? 0 : getGroupe().hashCode());
+    result = (prime * result) + ((getAdresse() == null) ? 0 : getAdresse().hashCode());
+    result = (prime * result) + ((getCodePostal() == null) ? 0 : getCodePostal().hashCode());
+    result = (prime * result) + ((getVille() == null) ? 0 : getVille().hashCode());
+    result = (prime * result) + ((getPays() == null) ? 0 : getPays().hashCode());
+    result = (prime * result) + ((getNumeroTelephone() == null) ? 0 : getNumeroTelephone().hashCode());
+    result = (prime * result) + ((getEmail() == null) ? 0 : getEmail().hashCode());
+    result = (prime * result) + ((getStatus() == null) ? 0 : getStatus().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Participant p = (Participant) obj;
+    if (getNumeroParticipant() == null) { if (p.getNumeroParticipant() == null) { return false; } } else if (!getNumeroParticipant().equals(p.getNumeroParticipant())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Participant [id=")
+           .append(numeroParticipant)
+           .append(", nom=").append(nom)
+           .append(", prenom=").append(prenom)
+           .append(", pseudonyme=").append(pseudonyme)
+           .append(", groupe=").append(groupe)
+           .append(arrived ? ", arrivé" : "")
+           .append(", adresse=").append(adresse)
+           .append(", zip=").append(codePostal)
+           .append(", ville=").append(ville)
+           .append(", pays=").append(pays)
+           .append(", inscrit=").append(dateInscription)
+           .append(", numeroTelephone=").append(numeroTelephone)
+           .append(", email=").append(email)
+           .append(withMachine ? ", avec machine" : "")
+           .append(hereDay1 ? ", J1" : "")
+           .append(hereDay1 ? ", J2" : "")
+           .append(hereDay1 ? ", J3" : "")
+           .append(sleepingOnSite ? ", dodo in situ" : "")
+           .append(useAmigabus ? ", amigabus" : "")
+           .append(", paiement=").append(modePaiement)
+           .append(", status=").append(status)
+           .append(", montant=").append(sommeRecue)
+           .append(", créé=").append(dateCreation)
+           .append(", modifié=").append(dateModification)
+           .append(enabled ? ", roles=" + roles : ", inactif")
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 25 - 0
src/main/java/fr/triplea/demovote/persistence/model/ParticipantModePaiement.java

@@ -0,0 +1,25 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ParticipantModePaiement 
+{
+  
+  CHEQUE("Chèque"), VIREMENT("Virement"), PAYPAL("Paypal"), ESPECES("Espèces"), AUTRE("Autre");
+
+  private String mode;
+  
+  private static Map<String, ParticipantModePaiement> types = new HashMap<String, ParticipantModePaiement>();
+
+  static { for(ParticipantModePaiement r : EnumSet.allOf(ParticipantModePaiement.class)) { types.put(r.toString(), r); } }
+
+  public static ParticipantModePaiement getType(String mode) { return types.get(mode); }
+
+  private ParticipantModePaiement(String mode) { this.mode = mode; }
+
+  @Override
+  public String toString() { return mode; }
+
+}

+ 25 - 0
src/main/java/fr/triplea/demovote/persistence/model/ParticipantStatus.java

@@ -0,0 +1,25 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ParticipantStatus 
+{
+  
+  EN_ATTENTE("En attente"), PAYE_CHEQUE("Payé chèque"), PAYE_ESPECES("Payé espèces"), VIREMENT_BANCAIRE("Virement bancaire"), VIREMENT_PAYPAL("Virement Paypal"), ORGA("Orga"), GUEST("Guest");
+
+  private String status;
+  
+  private static Map<String, ParticipantStatus> liste = new HashMap<String, ParticipantStatus>();
+
+  static { for(ParticipantStatus r : EnumSet.allOf(ParticipantStatus.class)) { liste.put(r.toString(), r); } }
+
+  public static ParticipantStatus getType(String s) { return liste.get(s); }
+
+  private ParticipantStatus(String mode) { this.status = mode; }
+
+  @Override
+  public String toString() { return status; }
+
+}

+ 111 - 0
src/main/java/fr/triplea/demovote/persistence/model/Preference.java

@@ -0,0 +1,111 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.time.LocalDateTime;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.util.StringUtils;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+
+@Entity(name = "vote.preferences")
+@Table(name = "preferences")
+public class Preference
+{
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @UpdateTimestamp
+  private LocalDateTime dateModification;
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_preference")
+  private Integer numeroPreference;
+
+  @ManyToOne
+  @JoinColumn(name="numero_participant", referencedColumnName="numero_participant")
+  private Participant participant;
+  
+  private Integer numeroTraitement;
+
+  @Column(length = 4000, nullable = false)
+  private String valeurs;
+  
+  
+  public Preference() { super(); }
+  
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+
+  public LocalDateTime getDateModification() { return this.dateModification; }
+  
+  public Integer getNumeroPreference() { return this.numeroPreference; }
+  
+  public void setParticipant(Participant p) { this.participant = p; }
+  public Participant getParticipant() { return this.participant; }
+  
+  public void setNumeroTraitement(int t) { this.numeroTraitement = Integer.valueOf(t); }
+  public Integer getNumeroTraitement() { return this.numeroTraitement; }
+  
+  public void setValeurs(String str) { if (str != null) { this.valeurs = StringUtils.truncate(str, 4000); } }
+  public String getValeurs() { return this.valeurs; }
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getNumeroPreference() == null) ? 0 : getNumeroPreference().hashCode());
+    result = (prime * result) + ((getParticipant() == null) ? 0 : getParticipant().hashCode());
+    result = (prime * result) + ((getNumeroTraitement() == null) ? 0 : getNumeroTraitement().hashCode());
+    result = (prime * result) + ((getValeurs() == null) ? 0 : getValeurs().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Preference p = (Preference) obj;
+    if (getNumeroPreference() == null) { if (p.getNumeroPreference() == null) { return false; } } else if (!getNumeroPreference().equals(p.getNumeroPreference())) { return false; }
+    if (getParticipant() == null) { if (p.getParticipant() == null) { return false; } } else if (!getParticipant().equals(p.getParticipant())) { return false; }
+    if (getNumeroTraitement() == null) { if (p.getNumeroTraitement() == null) { return false; } } else if (!getNumeroTraitement().equals(p.getNumeroTraitement())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Preference [id=")
+           .append(numeroPreference)
+           .append(", participant=").append(participant)
+           .append(", numeroTraitement=").append(numeroTraitement)
+           .append(", valeurs=").append(valeurs)
+           .append(", créé=").append(dateCreation)
+           .append(", modifié=").append(dateModification)
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 102 - 0
src/main/java/fr/triplea/demovote/persistence/model/Presentation.java

@@ -0,0 +1,102 @@
+package fr.triplea.demovote.persistence.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToOne;
+import jakarta.persistence.Table;
+
+@Entity(name = "vote.presentations")
+@Table(name = "presentations")
+public class Presentation
+{
+  
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_presentation")
+  private Integer numeroPresentation;
+
+  @ManyToOne
+  @JoinColumn(name="numero_categorie", referencedColumnName="numero_categorie")
+  private Categorie categorie;
+
+  @OneToOne
+  @JoinColumn(name="numero_production", referencedColumnName="numero_production")
+  private Production production;
+  
+  private Integer numeroOrdre;
+
+  private Integer nombrePoints;
+
+  private Integer nombrePolePosition;
+
+  
+  public Presentation() { super(); }
+
+  
+  public Integer getNumeroPresentation() { return this.numeroPresentation; }
+  
+  public void setCategorie(Categorie c) { this.categorie = c; }
+  public Categorie getCategorie() { return this.categorie; }
+  
+  public void setProduction(Production p) { this.production = p; }
+  public Production getProduction() { return this.production; }
+  
+  public void setNumeroOrdre(int n) { this.numeroOrdre = Integer.valueOf(n); }
+  public Integer getNumeroOrdre() { return this.numeroOrdre; }
+  
+  public void setNombrePoints(int n) { this.nombrePoints = Integer.valueOf(n); }
+  public Integer getNombrePoints() { return this.nombrePoints; }
+  
+  public void setNombrePolePosition(int n) { this.nombrePolePosition = Integer.valueOf(n); }
+  public Integer getNombrePolePosition() { return this.nombrePolePosition; }
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getNumeroPresentation() == null) ? 0 : getNumeroPresentation().hashCode());
+    result = (prime * result) + ((getCategorie() == null) ? 0 : getCategorie().hashCode());
+    result = (prime * result) + ((getProduction() == null) ? 0 : getProduction().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Presentation p = (Presentation) obj;
+    if (getNumeroPresentation() == null) { if (p.getNumeroPresentation() == null) { return false; } } else if (!getNumeroPresentation().equals(p.getNumeroPresentation())) { return false; }
+    if (getCategorie() == null) { if (p.getCategorie() == null) { return false; } } else if (!getCategorie().equals(p.getCategorie())) { return false; }
+    if (getProduction() == null) { if (p.getProduction() == null) { return false; } } else if (!getProduction().equals(p.getProduction())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Presentation [id=")
+           .append(numeroPresentation)
+           .append(", categorie=").append(categorie)
+           .append(", production=").append(production)
+           .append(", numeroOrdre=").append(numeroOrdre)
+           .append(", nombrePoints=").append(nombrePoints)
+           .append(", nombrePolePosition=").append(nombrePolePosition)
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 101 - 0
src/main/java/fr/triplea/demovote/persistence/model/Privilege.java

@@ -0,0 +1,101 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.util.StringUtils;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+
+@Entity(name = "vote.privileges")
+@Table(name = "privileges")
+public class Privilege
+{
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @UpdateTimestamp
+  private LocalDateTime dateModification;
+  
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_privilege")
+  private Integer numeroPrivilege;
+ 
+  @Column(length = 128, nullable = false)
+  private String libelle;
+  
+  @ManyToMany(mappedBy = "privileges")
+  private List<Role> roles;
+ 
+  
+  public Privilege() { super(); }
+
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+  
+  public LocalDateTime getDateModification() { return this.dateModification; }
+  
+  public void setNumeroPrivilege(Integer numeroPrivilege) { this.numeroPrivilege = numeroPrivilege; }
+  public Integer getNumeroPrivilege() { return this.numeroPrivilege; }
+  
+  public void setLibelle(String str) { if (str != null) { this.libelle = StringUtils.truncate(str, 128); } }
+  public String getLibelle() { return this.libelle; }
+  
+  public List<Role> getRoles() { return roles; }
+  public void setRoles(final List<Role> roles) { this.roles = roles; }
+  
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getLibelle() == null) ? 0 : getLibelle().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Privilege p = (Privilege) obj;
+    if (getNumeroPrivilege() == null) { if (p.getNumeroPrivilege() == null) { return false; } } else if (!getNumeroPrivilege().equals(p.getNumeroPrivilege())) { return false; }
+    if (getLibelle() == null) { if (p.getLibelle() == null) { return false; } } else if (!getLibelle().equals(p.getLibelle())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Privilege [id=")
+           .append(numeroPrivilege)
+           .append(", libelle=").append(libelle)
+           .append(", créé=").append(dateCreation)
+           .append(", modifié=").append(dateModification)
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 245 - 0
src/main/java/fr/triplea/demovote/persistence/model/Production.java

@@ -0,0 +1,245 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.sql.Types;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.JdbcTypeCode;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.util.StringUtils;
+
+import io.hypersistence.utils.hibernate.type.basic.Inet;
+import io.hypersistence.utils.hibernate.type.basic.PostgreSQLInetType;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Lob;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+import jakarta.persistence.Transient;
+
+@Entity(name = "vote.productions")
+@Table(name = "productions")
+public class Production
+{
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @UpdateTimestamp
+  private LocalDateTime dateModification;
+  
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_production")
+  private Integer numeroProduction;
+
+  @Column(name = "flag_actif")
+  private Boolean enabled = true;
+  
+  @ManyToOne
+  @JoinColumn(name="numero_participant", referencedColumnName="numero_participant")
+  private Participant participant;
+
+  @Type(PostgreSQLInetType.class)
+  @Column(name = "adresse_ip", columnDefinition = "inet")
+  private Inet adresseIP;
+ 
+  @Enumerated(EnumType.STRING) 
+  private ProductionType type;
+  
+  @Column(length = 256, nullable = false)
+  private String titre = "unknown compo entry name";
+  
+  @Column(length = 256, nullable = false)
+  private String auteurs = "unknown author(s)";
+  
+  @Column(length = 256)
+  private String groupes = "unknown group(s)";
+
+  @Column(length = 128)
+  private String plateforme;
+
+  private String commentaire;
+
+  private String informationsPrivees;
+
+  @Column(length = 256)
+  private String nomArchive;
+
+  @Lob @JdbcTypeCode(Types.BINARY)
+  @Column(name="archive")
+  private byte[] archive;
+
+  @Lob @JdbcTypeCode(Types.BINARY)
+  @Column(name="vignette")
+  private byte[] vignette;
+  
+  private Integer numeroVersion = 1;
+  
+
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production")
+  private List<Presentation> presentations;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production01")
+  private List<Bulletin> bulletins01;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production02")
+  private List<Bulletin> bulletins02;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production03")
+  private List<Bulletin> bulletins03;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production04")
+  private List<Bulletin> bulletins04;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production05")
+  private List<Bulletin> bulletins05;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production06")
+  private List<Bulletin> bulletins06;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production07")
+  private List<Bulletin> bulletins07;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production08")
+  private List<Bulletin> bulletins08;
+  
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production09")
+  private List<Bulletin> bulletins09;
+
+  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "production10")
+  private List<Bulletin> bulletins10;
+
+  
+  public Production() { super(); }
+
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+  
+  public LocalDateTime getDateModification() { return this.dateModification; }
+  
+  public Integer getNumeroProduction() { return this.numeroProduction; }
+  
+  public void setEnabled(boolean b) { this.enabled = Boolean.valueOf(b); }
+  public Boolean getEnabled() { return this.enabled; }
+  @Transient
+  public boolean isEnabled() { return (getEnabled().booleanValue()); }
+  
+  public void setParticipant(Participant p) { this.participant = p; }
+  public Participant getParticipant() { return this.participant; }
+  
+  public void setAdresseIP(Inet ip) { this.adresseIP = ip; }
+  public Inet getAdresseIP() { return this.adresseIP; }
+  
+  public void setType(ProductionType enu) { this.type = enu; }
+  public ProductionType getType() { return this.type; }
+  
+  public void setTitre(String str) { if (str != null) { this.titre = StringUtils.truncate(str, 256); } }
+  public String getTitre() { return this.titre; }
+  
+  public void setAuteurs(String str) { if (str != null) { this.auteurs = StringUtils.truncate(str, 256); } }
+  public String getAuteurs() { return this.auteurs; }
+  
+  public void setGroupes(String str) { if (str != null) { this.groupes = StringUtils.truncate(str, 256); } }
+  public String getGroupes() { return this.groupes; }
+  
+  public void setPlateforme(String str) { if (str != null) { this.plateforme = StringUtils.truncate(str, 128); } }
+  public String getPlateforme() { return this.plateforme; }
+  
+  public void setCommentaire(String str) { this.commentaire = new String(str); }
+  public String getCommentaire() { return this.commentaire; }
+  
+  public void setInformationsPrivees(String str) { this.informationsPrivees = new String(str); }
+  public String getInformationsPrivees() { return this.informationsPrivees; }
+  
+  public void setNomArchive(String str) { if (str != null) { this.nomArchive = StringUtils.truncate(str, 256); } }
+  public String getNomArchive() { return this.nomArchive; }
+  
+  public void setArchive(byte[] a) { this.archive = a; }
+  public byte[] getArchive() { return this.archive; }
+  
+  public void setVignette(byte[] v) { this.vignette = v; }
+  public byte[] getVignette() { return this.vignette; }
+ 
+  public void setNumeroVersion(int n) { this.numeroVersion = Integer.valueOf(n); }
+  public Integer getNumeroVersion() { return this.numeroVersion; }
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getNumeroProduction() == null) ? 0 : getNumeroProduction().hashCode());
+    result = (prime * result) + ((getEnabled() == null) ? 0 : getEnabled().hashCode());
+    result = (prime * result) + ((getParticipant() == null) ? 0 : getParticipant().hashCode());
+    result = (prime * result) + ((getAdresseIP() == null) ? 0 : getAdresseIP().hashCode());
+    result = (prime * result) + ((getType() == null) ? 0 : getType().hashCode());
+    result = (prime * result) + ((getTitre() == null) ? 0 : getTitre().hashCode());
+    result = (prime * result) + ((getAuteurs() == null) ? 0 : getAuteurs().hashCode());
+    result = (prime * result) + ((getGroupes() == null) ? 0 : getGroupes().hashCode());
+    result = (prime * result) + ((getPlateforme() == null) ? 0 : getPlateforme().hashCode());
+    result = (prime * result) + ((getCommentaire() == null) ? 0 : getCommentaire().hashCode());
+    result = (prime * result) + ((getInformationsPrivees() == null) ? 0 : getInformationsPrivees().hashCode());
+    result = (prime * result) + ((getNomArchive() == null) ? 0 : getNomArchive().hashCode());
+    result = (prime * result) + ((getNumeroVersion() == null) ? 0 : getNumeroVersion().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Production p = (Production) obj;
+    if (getNumeroProduction() == null) { if (p.getNumeroProduction() == null) { return false; } } else if (!getNumeroProduction().equals(p.getNumeroProduction())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Production [id=")
+           .append(numeroProduction)
+           .append(", participant=").append(participant)
+           .append(", IP=").append(adresseIP)
+           .append(", type=").append(type)
+           .append(", titre=").append(titre)
+           .append(", auteurs=").append(auteurs)
+           .append(", groupes=").append(groupes)
+           .append(", plateforme=").append(plateforme)
+           .append(", commentaire=").append(commentaire)
+           .append(", nomArchive=").append(nomArchive)
+           .append(", archive=").append("" + archive.length + " bytes")
+           .append(", vignette=").append("" + vignette.length + " bytes")
+           .append(", version=").append(numeroVersion)
+           .append(", créé=").append(dateCreation)
+           .append(", modifié=").append(dateModification)
+           .append(enabled ? "" : ", inactif")
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 25 - 0
src/main/java/fr/triplea/demovote/persistence/model/ProductionType.java

@@ -0,0 +1,25 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ProductionType 
+{ 
+  
+  EXECUTABLE("Exécutable"), GRAPHE("Graphe"), MUSIQUE("Musique"), VIDEO("Vidéo"), TOPIC("Topic"), AUTRE("Autre");
+
+  private String type;
+  
+  private static Map<String, ProductionType> types = new HashMap<String, ProductionType>();
+
+  static { for(ProductionType r : EnumSet.allOf(ProductionType.class)) { types.put(r.toString(), r); } }
+
+  public static ProductionType getType(String type) { return types.get(type); }
+
+  private ProductionType(String type) { this.type = type; }
+
+  @Override
+  public String toString() { return type; }
+
+}

+ 120 - 0
src/main/java/fr/triplea/demovote/persistence/model/Role.java

@@ -0,0 +1,120 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.util.StringUtils;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.JoinTable;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+import jakarta.persistence.Transient;
+
+@Entity(name = "vote.roles")
+@Table(name = "roles")
+public class Role
+{
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @UpdateTimestamp
+  private LocalDateTime dateModification;
+  
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_role")
+  private Integer numeroRole;
+  
+  @Column(name = "flag_actif")
+  private Boolean enabled;
+  
+  @Column(length = 64, nullable = false)
+  private String libelle;
+
+  @ManyToMany
+  @JoinTable(name = "roles_privileges", 
+             joinColumns = @JoinColumn(name = "numero_role", referencedColumnName = "numero_role"), 
+             inverseJoinColumns = @JoinColumn(name = "numero_privilege", referencedColumnName = "numero_privilege"))
+  private List<Privilege> privileges;
+
+  @ManyToMany(mappedBy = "roles")
+  private List<Participant> participants;
+
+
+  public Role() { super(); }
+
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+  
+  public LocalDateTime getDateModification() { return this.dateModification; }
+  
+  public Integer getNumeroRole() { return this.numeroRole; }
+  
+  public void setEnabled(boolean b) { this.enabled = Boolean.valueOf(b); }
+  public Boolean getEnabled() { return this.enabled; }
+  @Transient
+  public boolean isEnabled() { return (getEnabled().booleanValue()); }
+  
+  public void setLibelle(String str) { if (str != null) { this.libelle = StringUtils.truncate(str, 64); } }
+  public String getLibelle() { return this.libelle; }
+
+  public List<Privilege> getPrivileges() { return this.privileges; }
+  public void setPrivileges(final List<Privilege> privileges) { this.privileges = privileges; }
+  
+  public List<Participant> getParticipants() { return participants; }
+  public void setUsers(final List<Participant> participants) { this.participants = participants; }
+
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getLibelle() == null) ? 0 : getLibelle().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Role r = (Role) obj;
+    if (getLibelle() == null) { if (r.getLibelle() == null) { return false; } } else if (!getLibelle().equals(r.getLibelle())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Role [id=")
+           .append(numeroRole)
+           .append(", libelle=").append(libelle)
+           .append(", créé=").append(dateCreation)
+           .append(", modifié=").append(dateModification)
+           .append(enabled ? "" : ", inactif")
+           .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 117 - 0
src/main/java/fr/triplea/demovote/persistence/model/Variable.java

@@ -0,0 +1,117 @@
+package fr.triplea.demovote.persistence.model;
+
+import java.time.LocalDateTime;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.util.StringUtils;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+
+@Entity(name = "vote.variables")
+@Table(name = "variables")
+public class Variable
+{
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @CreationTimestamp
+  private LocalDateTime dateCreation;
+  
+  @Temporal(TemporalType.TIMESTAMP)
+  @UpdateTimestamp
+  private LocalDateTime dateModification;
+  
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Column(name = "numero_variable")
+  private Integer numeroVariable;
+  
+  @Column(length = 64, nullable = false)
+  private String type;
+
+  @Column(length = 64, nullable = false)
+  private String code;
+
+  @Column(length = 4000)
+  private String valeur;
+
+  @Column(length = 4000)
+  private String notes;
+  
+  
+  public Variable() { super(); }
+
+  
+  public LocalDateTime getDateCreation() { return this.dateCreation; }
+  
+  public LocalDateTime getDateModification() { return this.dateModification; }
+  
+  public Integer getNumeroVariable() { return this.numeroVariable; }
+  
+  public void setType(String str) { if (str != null) { this.type = StringUtils.truncate(str, 64); } }
+  public String getType() { return this.type; }
+  
+  public void setCode(String str) { if (str != null) { this.code = StringUtils.truncate(str, 64); } }
+  public String getCode() { return this.code; }
+  
+  public void setValeur(String str) { if (str != null) { this.valeur = StringUtils.truncate(str, 4000); } }
+  public String getValeur() { return this.valeur; }
+  
+  public void setNotes(String str) { if (str != null) { this.notes = StringUtils.truncate(str, 4000); } }
+  public String getNotes() { return this.notes; }
+  
+
+  @Override
+  public int hashCode() 
+  {
+    final int prime = 42;
+    int result = 1;
+    result = (prime * result) + ((getType() == null) ? 0 : getType().hashCode());
+    result = (prime * result) + ((getCode() == null) ? 0 : getCode().hashCode());
+    result = (prime * result) + ((getValeur() == null) ? 0 : getValeur().hashCode());
+    result = (prime * result) + ((getNotes() == null) ? 0 : getNotes().hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) 
+  {
+    if (this == obj) { return true; }
+    if (obj == null) { return false; }
+    if (getClass() != obj.getClass()) { return false; }
+      
+    final Variable v = (Variable) obj;
+    if (getType() == null) { if (v.getType() == null) { return false; } } else if (!getType().equals(v.getType())) { return false; }
+    if (getCode() == null) { if (v.getCode() == null) { return false; } } else if (!getCode().equals(v.getCode())) { return false; }
+    if (getValeur() == null) { if (v.getValeur() == null) { return false; } } else if (!getValeur().equals(v.getValeur())) { return false; }
+    if (getNotes() == null) { if (v.getNotes() == null) { return false; } } else if (!getNotes().equals(v.getNotes())) { return false; }
+    
+    return true;
+  }
+
+  @Override
+  public String toString() 
+  {
+    final StringBuilder builder = new StringBuilder();
+    
+    builder.append("Variable [id=")
+           .append(numeroVariable)
+           .append(", type=").append(type)
+           .append(", code=").append(code)
+           .append(", valeur=").append(valeur)
+           .append(", notes=").append(notes)
+           .append(", créé=").append(dateCreation)
+           .append(", modifié=").append(dateModification)
+          .append("]");
+
+    return builder.toString();
+  }
+
+}

+ 213 - 0
src/main/java/fr/triplea/demovote/spring/CreateDefaultValues.java

@@ -0,0 +1,213 @@
+package fr.triplea.demovote.spring;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import fr.triplea.demovote.persistence.dao.ParticipantRepository;
+import fr.triplea.demovote.persistence.dao.PrivilegeRepository;
+import fr.triplea.demovote.persistence.dao.RoleRepository;
+import fr.triplea.demovote.persistence.dao.VariableRepository;
+import fr.triplea.demovote.persistence.model.Participant;
+import fr.triplea.demovote.persistence.model.Privilege;
+import fr.triplea.demovote.persistence.model.Role;
+import fr.triplea.demovote.persistence.model.Variable;
+
+@Component
+public class CreateDefaultValues implements ApplicationListener<ContextRefreshedEvent>
+{
+
+  private final static String EMAIL_ADMIN = "pierre.tonthat@free.fr";
+  
+  boolean initialise = false;
+
+  @Autowired
+  private ParticipantRepository participantRepository;
+
+  @Autowired
+  private RoleRepository roleRepository;
+
+  @Autowired
+  private PrivilegeRepository privilegeRepository;
+
+  @Autowired
+  private VariableRepository variableRepository;
+
+  @Override
+  @Transactional
+  public void onApplicationEvent(ContextRefreshedEvent event) 
+  {
+    if (initialise) { return; } 
+    
+    Privilege listeVariablesPrivilege = addPrivilegeIfMissing("LISTE_VARIABLES");
+
+    Privilege pageAccueilPrivilege = addPrivilegeIfMissing("PAGE_ACCUEIL");
+
+    Privilege donneesPersonnellesPrivilege = addPrivilegeIfMissing("PAGE_DONNEES_PERSONNELLES");
+
+    Privilege listeParticipantsPrivilege = addPrivilegeIfMissing("LISTE_PARTICIPANTS");
+    Privilege modificationMotsDePasses = addPrivilegeIfMissing("MODIFICATION_MOTS_DE_PASSES");
+
+    Privilege listeProductionsPrivilegeAdmin = addPrivilegeIfMissing("LISTE_PRODUCTIONS_ADMIN");
+    Privilege listeProductionsPrivilegeUser = addPrivilegeIfMissing("LISTE_PRODUCTIONS_USER");
+    
+    Privilege listeCategoriesPrivilege = addPrivilegeIfMissing("LISTE_CATEGORIES");
+
+    Privilege listePresentationsPrivilege = addPrivilegeIfMissing("LISTE_PRESENTATIONS");
+
+    Privilege pageVoterPrivilege = addPrivilegeIfMissing("PAGE_VOTER");
+
+    Privilege pageResultatsPrivilege = addPrivilegeIfMissing("PAGE_RESULTATS");
+
+    Privilege pageMessageriePrivilege = addPrivilegeIfMissing("PAGE_MESSAGERIE");
+
+    Privilege pagePlanningPrivilege = addPrivilegeIfMissing("PAGE_PLANNING");
+
+    Privilege pageCamerasPrivilege = addPrivilegeIfMissing("PAGE_CAMERAS");    
+    
+    List<Privilege> adminPrivileges = Arrays.asList(listeVariablesPrivilege, modificationMotsDePasses, listeCategoriesPrivilege, listePresentationsPrivilege, listeProductionsPrivilegeAdmin);
+    List<Privilege> orgaPrivileges = Arrays.asList(listeParticipantsPrivilege);
+    List<Privilege> userPrivileges = Arrays.asList(pageAccueilPrivilege, donneesPersonnellesPrivilege, pageMessageriePrivilege, pagePlanningPrivilege, pageCamerasPrivilege, listeProductionsPrivilegeUser, pageVoterPrivilege, pageResultatsPrivilege);
+   
+    Role adminRole = addRoleIfMissing("Administrateur", adminPrivileges);
+    Role orgaRole = addRoleIfMissing("Organisateur", orgaPrivileges);
+    Role userRole = addRoleIfMissing("Participant", userPrivileges);
+    
+    
+    List<Participant> participants = participantRepository.findAll();
+    
+    for (Participant participant : participants)
+    {
+      List<Role> roles = participant.getRoles();
+      
+      if (roles == null) 
+      { 
+        participant.setRoles(Arrays.asList(userRole)); 
+        participantRepository.saveAndFlush(participant);
+      } 
+      else 
+      { 
+        if (!roles.contains(userRole)) 
+        { 
+          participant.setRoles(roles); 
+          participantRepository.saveAndFlush(participant);
+        }
+      }
+      
+      if (participant.getEmail().equalsIgnoreCase(CreateDefaultValues.EMAIL_ADMIN))
+      {
+        if (!roles.contains(adminRole)) 
+        { 
+          roles.add(adminRole);
+          participant.setRoles(roles); 
+          participantRepository.saveAndFlush(participant);
+        }
+        if (!roles.contains(orgaRole)) 
+        { 
+          roles.add(orgaRole);
+          participant.setRoles(roles); 
+          participantRepository.saveAndFlush(participant);
+        }
+      }
+    }
+
+    
+    addVariableIfMissing("Application", "TIME_ZONE", "Europe/Paris");
+    addVariableIfMissing("Application", "LIBELLE_COURT_JOUR1", "Ven1");
+    addVariableIfMissing("Application", "LIBELLE_COURT_JOUR2", "Sam2");
+    addVariableIfMissing("Application", "LIBELLE_COURT_JOUR3", "Dim3");
+    addVariableIfMissing("Application", "LIBELLE_LONG_JOUR1", "Vendredi 1er Novembre");
+    addVariableIfMissing("Application", "LIBELLE_LONG_JOUR2", "Samedi 2 Novembre");
+    addVariableIfMissing("Application", "LIBELLE_LONG_JOUR3", "Dimanche 3 Novembre");
+
+    addVariableIfMissing("Accueil", "PARTICIPANTS_ARRIVES_SEULEMENT", "TRUE");
+    
+    addVariableIfMissing("Navigation", "LISTE_PARTICIPANTS_MAX", "300");
+    addVariableIfMissing("Navigation", "LISTE_VARIABLES_MAX", "100");
+    
+    addVariableIfMissing("Catégories", "ETAPE1_DEADLINE_EFFECTUEE", "TRUE");
+    addVariableIfMissing("Catégories", "ETAPE2_SCRUTIN_CLOTURE", "TRUE");
+    addVariableIfMissing("Catégories", "ETAPE3_RESULTATS_DEMASQUES", "TRUE");
+    
+    addVariableIfMissing("Productions", "APERCU_SONORE_DEBUT", "10");
+    addVariableIfMissing("Productions", "APERCU_SONORE_LONGUEUR", "10");
+    addVariableIfMissing("Productions", "APERCU_IMAGE_TAILLE_MAX", "480");
+    addVariableIfMissing("Productions", "TAILLE_LIMITE_STOCKAGE_BASE", "4");
+    
+    addVariableIfMissing("Résultats", "NOMBRE_CHOIX", "3");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_01", "3");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_02", "2");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_03", "1");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_04", "0");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_05", "0");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_06", "0");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_07", "0");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_08", "0");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_09", "0");
+    addVariableIfMissing("Résultats", "POINTS_POSITION_10", "0");
+    
+    addVariableIfMissing("Messages", "PAGE_ACCUEIL", "<span class=\"texte\">Bienvenue dans l''intranet alchimique : <ul><li>messagerie locale</li><li>uploads et vote pour la démoparty</li><li>planning</li><li>webcams</li><li>etc</li></ul></span>");
+    addVariableIfMissing("Messages", "PAGE_MENU", "<span style=\"color:red;display:none;visibility:hidden;\">La deadline est décrétée !</span>");
+
+    addVariableIfMissing("Caméras", "RECUPERATION_ACTIVE", "TRUE");
+    addVariableIfMissing("Caméras", "RECUPERATION_IMAGE_1", "https://www.triplea.fr/alchimie/images/webcams/hirezcam.jpg");
+    addVariableIfMissing("Caméras", "RECUPERATION_IMAGE_2", "https://www.triplea.fr/alchimie/images/webcams/mobilecam.jpg");
+    addVariableIfMissing("Caméras", "RECUPERATION_IMAGE_3", "https://www.triplea.fr/alchimie/images/webcams/mobilecam2.jpg");
+    addVariableIfMissing("Caméras", "RECUPERATION_IMAGE_4", "NONE");
+    addVariableIfMissing("Caméras", "RECUPERATION_PAUSE", "25");
+    
+    initialise = true;
+  }
+
+  @Transactional
+  public Privilege addPrivilegeIfMissing(final String libelle) 
+  {
+    Privilege privilege = privilegeRepository.findByLibelle(libelle);
+    
+    if (privilege == null) 
+    {
+      privilege = new Privilege();
+      privilege.setLibelle(libelle);
+      privilege = privilegeRepository.save(privilege);
+    }
+    
+    return privilege;
+  }
+
+  @Transactional
+  public Role addRoleIfMissing(final String libelle, final List<Privilege> privileges) 
+  {
+    Role role = roleRepository.findByLibelle(libelle);
+    
+    if (role == null) { role = new Role(); role.setLibelle(libelle); }
+    
+    role.setPrivileges(privileges);
+    role = roleRepository.save(role);
+    
+    return role;
+  }
+
+  @Transactional
+  public void addVariableIfMissing(final String type, final String code, final String valeur) 
+  {
+    Variable variable = variableRepository.findByTypeAndCode(type, code);
+    
+    if (variable == null) 
+    { 
+      variable = new Variable(); 
+
+      variable.setType(type);
+      variable.setCode(code);
+      variable.setValeur(valeur);
+      
+      variableRepository.save(variable);
+    }
+    
+  }
+
+}

+ 32 - 0
src/main/java/fr/triplea/demovote/spring/MvcConfig.java

@@ -0,0 +1,32 @@
+package fr.triplea.demovote.spring;
+
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+
+@Configuration
+@ComponentScan(basePackages = { "fr.triplea.demovote.web" })
+@EnableWebMvc
+public class MvcConfig implements WebMvcConfigurer 
+{
+
+  public MvcConfig() { super(); }
+
+  @Override
+  public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { configurer.enable(); }
+
+  @Override
+  public void addResourceHandlers(final ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/", "/resources/"); }
+
+
+  @Bean
+  WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> enableDefaultServlet() { return (factory) -> factory.setRegisterDefaultServlet(true); }
+
+}

+ 135 - 0
src/main/java/fr/triplea/demovote/web/controller/BulletinController.java

@@ -0,0 +1,135 @@
+package fr.triplea.demovote.web.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.BulletinRepository;
+import fr.triplea.demovote.persistence.dao.CategorieRepository;
+import fr.triplea.demovote.persistence.dao.ParticipantRepository;
+import fr.triplea.demovote.persistence.dao.ProductionRepository;
+import fr.triplea.demovote.persistence.model.Bulletin;
+import fr.triplea.demovote.persistence.model.Categorie;
+import fr.triplea.demovote.persistence.model.Participant;
+import fr.triplea.demovote.persistence.model.Production;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/urne")
+public class BulletinController 
+{
+
+  @Autowired
+  private BulletinRepository bulletinRepository;
+
+  @Autowired
+  private CategorieRepository categorieRepository;
+
+  @Autowired
+  private ParticipantRepository participantRepository;
+
+  @Autowired
+  private ProductionRepository productionRepository;
+
+  @PostMapping(value = "/create")
+  //@PreAuthorize("hasRole('PAGE_VOTER')")
+  public ResponseEntity<Object> add(@RequestParam(required = true) int cat_id, @RequestParam(required = true) int part_id, @RequestParam(required = true) int prod_id) 
+  { 
+    Bulletin bul = bulletinRepository.findByCategorieAndParticipant(cat_id, part_id);
+    
+    Categorie cat = categorieRepository.findById(cat_id);
+    Participant part = participantRepository.findById(part_id);
+    Production prod = productionRepository.findById(prod_id);
+    
+    if (bul == null) 
+    { 
+      bul = new Bulletin();
+      
+      bul.setCategorie(cat); 
+      bul.setParticipant(part);
+    }
+    
+    if (bul != null) 
+    { 
+      Production prod01 = bul.getProduction01();
+
+      if (prod01 == null) { bul.setProduction01(prod); }
+      else
+      {
+        Production prod02 = bul.getProduction02();
+
+        if (prod02 == null) { bul.setProduction02(prod); }
+        else
+        {
+          Production prod03 = bul.getProduction03();
+
+          if (prod03 == null) { bul.setProduction03(prod); }
+          else
+          {
+            Production prod04 = bul.getProduction04();
+
+            if (prod04 == null) { bul.setProduction04(prod); }
+            else
+            {
+              Production prod05 = bul.getProduction05();
+
+              if (prod05 == null) { bul.setProduction05(prod); }
+              else
+              {
+                Production prod06 = bul.getProduction06();
+
+                if (prod06 == null) { bul.setProduction06(prod); }
+                else
+                {
+                  Production prod07 = bul.getProduction07();
+
+                  if (prod07 == null) { bul.setProduction07(prod); }
+                  else
+                  {
+                    Production prod08 = bul.getProduction08();
+
+                    if (prod08 == null) { bul.setProduction08(prod); }
+                    else
+                    {
+                      Production prod09 = bul.getProduction09();
+
+                      if (prod09 == null) { bul.setProduction09(prod); }
+                      else
+                      {
+                        Production prod10 = bul.getProduction10();
+
+                        if (prod10 == null) { bul.setProduction10(prod); }
+                      }
+                    }
+                  }
+                }
+              } 
+            }
+          }
+        }
+      }
+      
+      bulletinRepository.saveAndFlush(bul); 
+    }
+    
+    return ResponseEntity.status(HttpStatus.CREATED).body(bul);
+  }
+
+  @DeleteMapping(value = "/delete/{id}")
+  //@PreAuthorize("hasRole('PAGE_VOTER')")
+  public ResponseEntity<Object> remove(@PathVariable("id")int id) 
+  { 
+    if (id > 0) { bulletinRepository.deleteById(id); }
+    
+    return ResponseEntity.status(HttpStatus.ACCEPTED).build(); 
+  }
+
+}

+ 101 - 0
src/main/java/fr/triplea/demovote/web/controller/CategorieController.java

@@ -0,0 +1,101 @@
+package fr.triplea.demovote.web.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.CategorieRepository;
+import fr.triplea.demovote.persistence.model.Categorie;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/categorie")
+public class CategorieController 
+{
+
+  @Autowired
+  private CategorieRepository categorieRepository;
+
+
+  @GetMapping(value = "/list")
+  //@PreAuthorize("hasRole('LISTE_CATEGORIES')")
+  public List<Categorie> getList() 
+  { 
+    return categorieRepository.findAll(); 
+  }
+
+  @GetMapping(value = "/form/{id}")
+  //@PreAuthorize("hasRole('LISTE_CATEGORIES')")
+  public ResponseEntity<Categorie> getForm(@PathVariable("id") int id)
+  { 
+    Categorie c = categorieRepository.findById(id);
+    
+    if (c != null) { return ResponseEntity.ok(c); }
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @PostMapping(value = "/create")
+  //@PreAuthorize("hasRole('LISTE_CATEGORIES')")
+  public Categorie create(@RequestBody(required = true) Categorie categorie) 
+  { 
+    return categorieRepository.save(categorie);
+  }
+
+  @PutMapping(value = "/update/{id}")
+  //@PreAuthorize("hasRole('LISTE_CATEGORIES')")
+  public ResponseEntity<Object> update(@PathVariable("id") int id, @RequestBody(required = true) Categorie categorie) 
+  { 
+    Categorie found = categorieRepository.findById(id);
+    
+    if (found != null)
+    {
+      found.setLibelle(categorie.getLibelle());
+      found.setNumeroOrdre(categorie.getNumeroOrdre());
+      found.setEnabled(true);
+      
+      found.setAvaiable(categorie.isAvailable());
+      found.setUploadable(categorie.isUploadable());
+      found.setDisplayable(categorie.isDisplayable());
+      found.setPollable(categorie.isPollable());
+      found.setComputed(categorie.isComputed());
+
+      Categorie updated = categorieRepository.save(found); 
+    
+      return ResponseEntity.ok(updated);
+    }
+    
+    return ResponseEntity.notFound().build(); 
+  }
+
+  @DeleteMapping(value = "/retire/{id}")
+  //@PreAuthorize("hasRole('LISTE_CATEGORIES')")
+  public ResponseEntity<Object> disableCategorie(@PathVariable("id") int id) 
+  { 
+    Categorie c = categorieRepository.getReferenceById(id);
+    
+    if (c != null)
+    {
+      c.setEnabled(false); 
+      
+      categorieRepository.saveAndFlush(c);
+
+      return ResponseEntity.status(HttpStatus.FOUND).build();  
+    }      
+    
+    return ResponseEntity.notFound().build(); 
+  }
+
+}

+ 33 - 0
src/main/java/fr/triplea/demovote/web/controller/MessageController.java

@@ -0,0 +1,33 @@
+package fr.triplea.demovote.web.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.MessageRepository;
+import fr.triplea.demovote.persistence.model.Message;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/message")
+public class MessageController 
+{
+
+  @Autowired
+  private MessageRepository messageRepository;
+  
+  
+  @GetMapping(value = "/list/{id}")
+  //@PreAuthorize("hasRole('PAGE_MESSAGERIE')")
+  public List<Message> getList(@PathVariable("id") int id)
+  { 
+    return messageRepository.findAll(id, id); 
+  }
+
+}

+ 126 - 0
src/main/java/fr/triplea/demovote/web/controller/ParticipantController.java

@@ -0,0 +1,126 @@
+package fr.triplea.demovote.web.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.ParticipantRepository;
+import fr.triplea.demovote.persistence.model.Participant;
+import fr.triplea.demovote.persistence.model.ParticipantModePaiement;
+import fr.triplea.demovote.persistence.model.ParticipantStatus;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/participant")
+public class ParticipantController 
+{
+
+  @Autowired
+  private ParticipantRepository participantRepository;
+
+  
+
+  @GetMapping(value = "/list")
+  //@PreAuthorize("hasRole('LISTE_PARTICIPANTS')")
+  public List<Participant> getList() 
+  { 
+    return participantRepository.findAll(); 
+  }
+
+  @GetMapping(value = "/form/{id}")
+  //@PreAuthorize("hasRole('LISTE_PARTICIPANTS')")
+  public ResponseEntity<Participant> getForm(@PathVariable("id") int id) 
+  { 
+    Participant p = participantRepository.findById(id);
+
+    if (p != null) { return ResponseEntity.ok(p); }
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @PostMapping(value = "/create")
+  //@PreAuthorize("hasRole('LISTE_PARTICIPANTS')")
+  public Participant create(@RequestBody(required = true) Participant participant) 
+  { 
+    if (participant.getStatus() == null) { participant.setStatus(ParticipantStatus.EN_ATTENTE); }
+    if (participant.getModePaiement() == null) { participant.setModePaiement(ParticipantModePaiement.ESPECES); }
+    
+    return participantRepository.save(participant);
+  }
+
+  @PutMapping(value = "/update/{id}")
+  //@PreAuthorize("hasRole('LISTE_PARTICIPANTS')")
+  public ResponseEntity<Object> update(@PathVariable("id") int id, @RequestBody(required = true) Participant participant) 
+  { 
+    Participant found = participantRepository.findById(id);
+    
+    if (found != null)
+    {
+      found.setRoles(participant.getRoles());
+      found.setEnabled(true);
+
+      found.setNom(participant.getNom());
+      found.setPrenom(participant.getPrenom());
+      found.setPseudonyme(participant.getPseudonyme());
+      found.setGroupe(participant.getGroupe()); 
+      found.setMotDePasse(participant.getMotDePasse());
+      found.setPasswordExpired(participant.getPasswordExpired());
+      found.setDateExpiration(participant.getDateExpiration());
+      found.setDelaiDeconnexion(participant.getDelaiDeconnexion());
+      found.setAdresse(participant.getAdresse());
+      found.setCodePostal(participant.getCodePostal());
+      found.setVille(participant.getVille());
+      found.setPays(participant.getPays());
+      found.setNumeroTelephone(participant.getNumeroTelephone());
+      found.setEmail(participant.getEmail());
+      found.setStatus(participant.getStatus());
+      found.setWithMachine(participant.getWithMachine().booleanValue());
+      found.setCommentaire(participant.getCommentaire());
+      found.setHereDay1(participant.getHereDay1().booleanValue());
+      found.setHereDay2(participant.getHereDay2().booleanValue());
+      found.setHereDay3(participant.getHereDay3().booleanValue());
+      found.setSleepingOnSite(participant.getSleepingOnSite().booleanValue());
+      found.setUseAmigabus(participant.getUseAmigabus().booleanValue());
+      found.setModePaiement(participant.getModePaiement());
+      found.setDateInscription(participant.getDateInscription());
+      found.setSommeRecue(participant.getSommeRecue());
+      found.setArrived(participant.getArrived().booleanValue());
+      
+      Participant updated = participantRepository.save(found);
+    
+      return ResponseEntity.ok(updated);
+    }
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @DeleteMapping(value = "/delete/{id}")
+  //@PreAuthorize("hasRole('LISTE_PARTICIPANTS')")
+  public ResponseEntity<Object> disableParticipant(@PathVariable("id") int id) 
+  { 
+    Participant found = participantRepository.getReferenceById(id);
+    
+    if (found != null)
+    {
+      found.setEnabled(false); 
+      
+      participantRepository.saveAndFlush(found);
+
+      return ResponseEntity.ok().build();  
+    }      
+    
+    return ResponseEntity.notFound().build(); 
+  }
+
+}

+ 65 - 0
src/main/java/fr/triplea/demovote/web/controller/PreferenceController.java

@@ -0,0 +1,65 @@
+package fr.triplea.demovote.web.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.PreferenceRepository;
+import fr.triplea.demovote.persistence.model.Participant;
+import fr.triplea.demovote.persistence.model.Preference;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/preference")
+public class PreferenceController 
+{
+
+  @Autowired
+  private PreferenceRepository preferenceRepository;
+
+  
+  @PostMapping(value = "/list")
+  //@PreAuthorize("hasRole('LISTE_PREFERENCES')")
+  public List<Preference> get(@RequestParam(required = true) Participant numParticipant, @RequestParam(required = false) int numTraitement) 
+  { 
+    return preferenceRepository.findByParticipantAndTraitement(numParticipant, numTraitement); 
+  }
+
+  @PostMapping(value = "/create")
+  //@PreAuthorize("hasRole('LISTE_PREFERENCES')")
+  public Preference create(@RequestBody(required = true) Preference preference) 
+  { 
+    return  preferenceRepository.save(preference);
+  }
+
+  @PutMapping(value = "/update/{id}")
+  //@PreAuthorize("hasRole('LISTE_PREFERENCES')")
+  public ResponseEntity<Preference> update(@PathVariable("id") int id, @RequestBody(required = true) Preference preference) 
+  { 
+    Preference found = preferenceRepository.findById(id);
+    
+    if (found != null)
+    {
+      found.setParticipant(preference.getParticipant());
+      found.setNumeroTraitement(preference.getNumeroTraitement());
+      found.setValeurs(preference.getValeurs());
+      
+      preferenceRepository.save(found);
+    
+      return ResponseEntity.ok(found);
+    }
+    
+    return ResponseEntity.notFound().build();
+  }
+ 
+}

+ 32 - 0
src/main/java/fr/triplea/demovote/web/controller/PresentationController.java

@@ -0,0 +1,32 @@
+package fr.triplea.demovote.web.controller;
+
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.PresentationRepository;
+import fr.triplea.demovote.persistence.model.Presentation;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/presentation")
+public class PresentationController 
+{
+
+  @Autowired
+  private PresentationRepository presentationRepository;
+ 
+  @GetMapping(value = "/list")
+  //@PreAuthorize("hasRole('LISTE_PRESENTATIONS')")
+  public List<Presentation> getList() 
+  {
+    return presentationRepository.findAll(); 
+  }
+  
+}

+ 117 - 0
src/main/java/fr/triplea/demovote/web/controller/ProductionController.java

@@ -0,0 +1,117 @@
+package fr.triplea.demovote.web.controller;
+
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.ProductionRepository;
+import fr.triplea.demovote.persistence.model.Production;
+import fr.triplea.demovote.persistence.model.ProductionType;
+import io.hypersistence.utils.hibernate.type.basic.Inet;
+import jakarta.servlet.http.HttpServletRequest;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/production")
+public class ProductionController 
+{
+
+  @Autowired
+  private ProductionRepository productionRepository;
+
+  @Autowired 
+  private HttpServletRequest request;
+
+  
+  @GetMapping(value = "/list", params = {"type"})
+  //@PreAuthorize("hasAnyRole('LISTE_PRODUCTIONS_ADMIN', 'LISTE_PRODUCTIONS_USER')")
+  public List<Production> getList(@RequestParam(required = false) String type) 
+  { 
+    return productionRepository.findAll(); 
+  }
+ 
+  @GetMapping(value = "/form/{id}")
+  //@PreAuthorize("hasAnyRole('LISTE_PRODUCTIONS_ADMIN', 'LISTE_PRODUCTIONS_USER')")
+  public ResponseEntity<Production> getForm(@PathVariable("id") int id)
+  { 
+    Production p = productionRepository.findById(id);
+    
+    if (p != null) { return ResponseEntity.ok(p); }
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @PostMapping(value = "/create")
+  //@PreAuthorize("hasAnyRole('LISTE_PRODUCTIONS_ADMIN', 'LISTE_PRODUCTIONS_USER')")
+  public Production create(@RequestBody(required = true) Production production) 
+  { 
+    if (production.getType() == null) { production.setType(ProductionType.AUTRE); }
+    if (production.getNumeroVersion() == null) { production.setNumeroVersion(1); }
+    
+    return productionRepository.save(production);
+  }
+ 
+  @PutMapping(value = "/update/{id}")
+  //@PreAuthorize("hasAnyRole('LISTE_PRODUCTIONS_ADMIN', 'LISTE_PRODUCTIONS_USER')")
+  public ResponseEntity<Production> update(@PathVariable("id") int id, @RequestBody(required = true) Production production) 
+  { 
+    Production found = productionRepository.findById(id);
+    
+    if (found != null)
+    {
+      found.setParticipant(production.getParticipant());
+      found.setEnabled(true);
+      
+      found.setAdresseIP(new Inet(request.getRemoteAddr()));
+      found.setType(production.getType()); 
+      found.setTitre(production.getTitre());
+      found.setAuteurs(production.getAuteurs());
+      found.setGroupes(production.getGroupes());
+      found.setPlateforme(production.getPlateforme());
+      found.setCommentaire(production.getCommentaire());
+      found.setInformationsPrivees(production.getInformationsPrivees());
+      found.setNomArchive(production.getNomArchive());
+      found.setArchive(production.getArchive());
+      found.setVignette(production.getVignette());
+      found.setNumeroVersion(found.getNumeroVersion() +1);
+      
+      Production updated = productionRepository.save(found);
+    
+      return ResponseEntity.ok(updated);
+    }
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @DeleteMapping(value = "/delete/{id}")
+  //@PreAuthorize("hasAnyRole('LISTE_PRODUCTIONS_ADMIN', 'LISTE_PRODUCTIONS_USER')")
+  public ResponseEntity<Object> disableProduction(@PathVariable("id") int id) 
+  { 
+    Production found = productionRepository.getReferenceById(id);
+    
+    if (found != null)
+    {
+      found.setEnabled(false); 
+      
+      productionRepository.saveAndFlush(found);
+      
+      return ResponseEntity.ok().build();
+    }      
+    
+    return ResponseEntity.notFound().build(); 
+  }
+
+}

+ 90 - 0
src/main/java/fr/triplea/demovote/web/controller/VariableController.java

@@ -0,0 +1,90 @@
+package fr.triplea.demovote.web.controller;
+
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+//import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import fr.triplea.demovote.persistence.dao.VariableRepository;
+import fr.triplea.demovote.persistence.model.Variable;
+
+@CrossOrigin(origins = "http://localhost:4200")
+@RestController
+@RequestMapping("/demovote-api/v1/variable")
+public class VariableController 
+{
+
+  @Autowired
+  private VariableRepository variableRepository;
+
+
+  @GetMapping(value = "/list")
+  //@PreAuthorize("hasRole('LISTE_VARIABLES')")
+  public List<Variable> getList(@RequestParam(required = false) String type) 
+  { 
+    if (type != null) { return variableRepository.findByType(type); } 
+ 
+    return variableRepository.findAll(); 
+  }
+ 
+  @GetMapping(value = "/form/{id}")
+  //@PreAuthorize("hasRole('LISTE_VARIABLES')")
+  public ResponseEntity<Variable> getForm(@PathVariable int id) 
+  { 
+    Variable v = variableRepository.findById(id);
+    
+    if (v != null) { return ResponseEntity.ok(v); } 
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @PostMapping(value = "/create")
+  //@PreAuthorize("hasRole('LISTE_VARIABLES')")
+  public Variable create(@RequestBody(required = true) Variable variable) 
+  { 
+    return variableRepository.save(variable);
+  }
+ 
+  @PutMapping(value = "/update/{id}")
+  //@PreAuthorize("hasRole('LISTE_VARIABLES')")
+  public ResponseEntity<Variable> update(@PathVariable int id, @RequestBody(required = true) Variable variable) 
+  { 
+    Variable found = variableRepository.findById(id);
+    
+    if (found != null)
+    {
+      found.setType(variable.getType());
+      found.setCode(variable.getCode());
+      found.setValeur(variable.getValeur());
+      found.setNotes(variable.getNotes());
+      
+      Variable updated = variableRepository.save(found);
+    
+      return ResponseEntity.ok(updated);
+    }
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @DeleteMapping(value = "/delete/{id}")
+  //@PreAuthorize("hasRole('LISTE_VARIABLES')")
+  public ResponseEntity<Object> deleteVariable(@PathVariable int id) 
+  { 
+    variableRepository.deleteById(id);
+    
+    return ResponseEntity.ok().build();
+  }
+
+}

+ 13 - 0
src/main/resources/application.properties

@@ -0,0 +1,13 @@
+spring.application.name=demovote-backend
+
+spring.datasource.url=jdbc:postgresql://localhost:5432/vote
+spring.datasource.username=vote
+spring.datasource.password=Atari$Impact2024
+spring.jpa.hibernate.ddl-auto=validate
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+
+#spring.jpa.show-sql=true
+
+logging.level.org.springframework=INFO
+
+server.servlet.context-path=/

+ 13 - 0
src/test/java/fr/triplea/demovote/DemovoteApplicationTests.java

@@ -0,0 +1,13 @@
+package fr.triplea.demovote;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class DemovoteApplicationTests {
+
+	@Test
+	void contextLoads() {
+	}
+
+}