瀏覽代碼

dev en cours

rajah 6 月之前
父節點
當前提交
e103827dd2

+ 2 - 2
src/main/java/fr/triplea/demovote/CreateDefaultValues.java

@@ -142,7 +142,7 @@ public class CreateDefaultValues implements ApplicationListener<ContextRefreshed
       
       role.setLibelle(libelle); 
 
-      role = roleRepository.save(role);
+      role = roleRepository.saveAndFlush(role);
     }
      
     return role;
@@ -161,7 +161,7 @@ public class CreateDefaultValues implements ApplicationListener<ContextRefreshed
       variable.setCode(code);
       variable.setValeur(valeur);
       
-      variableRepository.save(variable);
+      variableRepository.saveAndFlush(variable);
     }
     
   }

+ 26 - 3
src/main/java/fr/triplea/demovote/dao/BulletinRepository.java

@@ -6,14 +6,37 @@ 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.dto.BulletinShort;
 import fr.triplea.demovote.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.numero_bulletin, "
+             + " u.numero_categorie, "
+             + " u.numero_participant, "
+             + " CASE WHEN u.numero_production01 IS NULL THEN 0 ELSE u.numero_production01 END AS numero_production01, "
+             + " CASE WHEN u.numero_production02 IS NULL THEN 0 ELSE u.numero_production02 END AS numero_production02, "
+             + " CASE WHEN u.numero_production03 IS NULL THEN 0 ELSE u.numero_production03 END AS numero_production03, "
+             + " CASE WHEN u.numero_production04 IS NULL THEN 0 ELSE u.numero_production04 END AS numero_production04, "
+             + " CASE WHEN u.numero_production05 IS NULL THEN 0 ELSE u.numero_production05 END AS numero_production05, "
+             + " CASE WHEN u.numero_production06 IS NULL THEN 0 ELSE u.numero_production06 END AS numero_production06, "
+             + " CASE WHEN u.numero_production07 IS NULL THEN 0 ELSE u.numero_production07 END AS numero_production07, "
+             + " CASE WHEN u.numero_production08 IS NULL THEN 0 ELSE u.numero_production08 END AS numero_production08, "
+             + " CASE WHEN u.numero_production09 IS NULL THEN 0 ELSE u.numero_production09 END AS numero_production09, "
+             + " CASE WHEN u.numero_production10 IS NULL THEN 0 ELSE u.numero_production10 END AS numero_production10, "
+             + " u.flag_valide "
+             + "FROM vote.bulletins AS u "
+             + "WHERE u.numero_categorie = :categorie AND u.numero_participant = :participant ")
+  BulletinShort 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 AND u.numero_participant = :participant ")
+  Bulletin getByCategorieAndParticipant(@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);
 

+ 23 - 2
src/main/java/fr/triplea/demovote/dao/ProductionRepository.java

@@ -15,8 +15,15 @@ import fr.triplea.demovote.model.Production;
 public interface ProductionRepository extends JpaRepository<Production, Integer> 
 {
 
-  @NativeQuery("SELECT DISTINCT p.* FROM vote.productions AS p WHERE p.numero_production = :id AND p.flag_actif IS TRUE ")
-  Production findById(@Param("id") int id);
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.productions AS p WHERE p.numero_production = :numero AND p.flag_actif IS TRUE ")
+  Production findById(@Param("numero") int numeroProduction);
+
+  @NativeQuery("SELECT DISTINCT "
+             + " p.* "
+             + "FROM vote.presentations AS s "
+             + "INNER JOIN vote.productions AS p ON s.numero_production = p.numero_production "
+             + "WHERE s.numero_production = :numeroProduction AND s.numero_categorie = :numeroCategorie AND p.flag_actif IS TRUE ")
+  Production findByIdLinkedByCategorie(@Param("numeroCategorie") int numeroCategorie, @Param("numeroProduction") int numeroProduction);
   
   @NativeQuery("SELECT DISTINCT " 
               + "TO_CHAR(p.date_creation, 'DD/MM/YYYY HH24:MI:SS') as date_creation, "
@@ -141,6 +148,20 @@ public interface ProductionRepository extends JpaRepository<Production, Integer>
       + "ORDER BY p.titre ASC ")
   List<ProductionItem> findUnlinked();
   
+  @NativeQuery("SELECT DISTINCT " 
+      + "p.numero_production, "
+      + "p.type, "
+      + "p.titre, "
+      + "p.auteurs, "
+      + "p.groupes, "
+      + "p.plateforme, "
+      + "s.numero_ordre "
+      + "FROM vote.productions AS p "
+      + "INNER JOIN vote.presentations AS s ON p.numero_production = s.numero_production "
+      + "WHERE s.numero_production = :production AND s.numero_categorie = :categorie "
+      + "  AND p.flag_actif IS TRUE ")
+  ProductionItem findChosen(@Param("categorie") int numeroCategorie, @Param("production") int numeroProduction);
+  
   @Override
   void delete(Production production);
   

+ 137 - 0
src/main/java/fr/triplea/demovote/dto/BulletinShort.java

@@ -0,0 +1,137 @@
+package fr.triplea.demovote.dto;
+
+public class BulletinShort
+{
+  int numeroBulletin;
+  
+  int numeroCategorie;
+  
+  int numeroParticipant;
+  
+  int numeroProduction01;
+  int numeroProduction02;
+  int numeroProduction03;
+  int numeroProduction04;
+  int numeroProduction05;
+  int numeroProduction06;
+  int numeroProduction07;
+  int numeroProduction08;
+  int numeroProduction09;
+  int numeroProduction10;
+  
+  boolean flagValide;
+  
+
+  public BulletinShort(int numeroBulletin, int numeroCategorie, int numeroParticipant, int numeroProduction01, int numeroProduction02, int numeroProduction03, int numeroProduction04, int numeroProduction05, int numeroProduction06, int numeroProduction07, int numeroProduction08, int numeroProduction09, int numeroProduction10, boolean flagValide) 
+  {
+    this.numeroBulletin = numeroBulletin;
+    this.numeroCategorie = numeroCategorie;
+    this.numeroParticipant = numeroParticipant;
+    this.numeroProduction01 = numeroProduction01;
+    this.numeroProduction02 = numeroProduction02;
+    this.numeroProduction03 = numeroProduction03;
+    this.numeroProduction04 = numeroProduction04;
+    this.numeroProduction05 = numeroProduction05;
+    this.numeroProduction06 = numeroProduction06;
+    this.numeroProduction07 = numeroProduction07;
+    this.numeroProduction08 = numeroProduction08;
+    this.numeroProduction09 = numeroProduction09;
+    this.numeroProduction10 = numeroProduction10;
+    this.flagValide = flagValide;
+  }
+  
+  
+  public void setNumeroBulletin(int numeroBulletin) { this.numeroBulletin = numeroBulletin; }
+  public int getNumeroBulletin() { return numeroBulletin; }
+
+  public void setNumeroCategorie(int numeroCategorie) { this.numeroCategorie = numeroCategorie; }
+  public int getNumeroCategorie() { return numeroCategorie; }
+
+  public void setNumeroParticipant(int numeroParticipant) { this.numeroParticipant = numeroParticipant; }
+  public int getNumeroParticipant() { return numeroParticipant; }
+  
+  public void setNumeroProduction01(int numeroProduction01) { this.numeroProduction01 = numeroProduction01; }
+  public void setNumeroProduction02(int numeroProduction02) { this.numeroProduction02 = numeroProduction02; }
+  public void setNumeroProduction03(int numeroProduction03) { this.numeroProduction03 = numeroProduction03; }
+  public void setNumeroProduction04(int numeroProduction04) { this.numeroProduction04 = numeroProduction04; }
+  public void setNumeroProduction05(int numeroProduction05) { this.numeroProduction05 = numeroProduction05; }
+  public void setNumeroProduction06(int numeroProduction06) { this.numeroProduction06 = numeroProduction06; }
+  public void setNumeroProduction07(int numeroProduction07) { this.numeroProduction07 = numeroProduction07; }
+  public void setNumeroProduction08(int numeroProduction08) { this.numeroProduction08 = numeroProduction08; }
+  public void setNumeroProduction09(int numeroProduction09) { this.numeroProduction09 = numeroProduction09; }
+  public void setNumeroProduction10(int numeroProduction10) { this.numeroProduction10 = numeroProduction10; }
+
+  public int getNumeroProduction01() { return this.numeroProduction01; }
+  public int getNumeroProduction02() { return this.numeroProduction02; }
+  public int getNumeroProduction03() { return this.numeroProduction03; }
+  public int getNumeroProduction04() { return this.numeroProduction04; }
+  public int getNumeroProduction05() { return this.numeroProduction05; }
+  public int getNumeroProduction06() { return this.numeroProduction06; }
+  public int getNumeroProduction07() { return this.numeroProduction07; }
+  public int getNumeroProduction08() { return this.numeroProduction08; }
+  public int getNumeroProduction09() { return this.numeroProduction09; }
+  public int getNumeroProduction10() { return this.numeroProduction10; }
+
+  public boolean hasProduction01() { return (this.numeroProduction01 > 0); }
+  public boolean hasProduction02() { return (this.numeroProduction02 > 0); }
+  public boolean hasProduction03() { return (this.numeroProduction03 > 0); }
+  public boolean hasProduction04() { return (this.numeroProduction04 > 0); }
+  public boolean hasProduction05() { return (this.numeroProduction05 > 0); }
+  public boolean hasProduction06() { return (this.numeroProduction06 > 0); }
+  public boolean hasProduction07() { return (this.numeroProduction07 > 0); }
+  public boolean hasProduction08() { return (this.numeroProduction08 > 0); }
+  public boolean hasProduction09() { return (this.numeroProduction09 > 0); }
+  public boolean hasProduction10() { return (this.numeroProduction10 > 0); }
+
+  public int getPlaceLibre(int max)
+  {
+    if (max >= 1) { if (!hasProduction01()) { return 1; } }
+    if (max >= 2) { if (!hasProduction02()) { return 2; } }
+    if (max >= 3) { if (!hasProduction03()) { return 3; } }
+    if (max >= 4) { if (!hasProduction04()) { return 4; } }
+    if (max >= 5) { if (!hasProduction05()) { return 5; } }
+    if (max >= 6) { if (!hasProduction06()) { return 6; } }
+    if (max >= 7) { if (!hasProduction07()) { return 7; } }
+    if (max >= 8) { if (!hasProduction08()) { return 8; } }
+    if (max >= 9) { if (!hasProduction09()) { return 9; } }
+    if (max >= 10) { if (!hasProduction10()) { return 10; } }
+    
+    return 0;
+  }
+
+  public int getPlace(int numero, int max)
+  {
+    if (max >= 1) { if (this.numeroProduction01 == numero) { return 1; } }
+    if (max >= 2) { if (this.numeroProduction02 == numero) { return 2; } }
+    if (max >= 3) { if (this.numeroProduction03 == numero) { return 3; } }
+    if (max >= 4) { if (this.numeroProduction04 == numero) { return 4; } }
+    if (max >= 5) { if (this.numeroProduction05 == numero) { return 5; } }
+    if (max >= 6) { if (this.numeroProduction06 == numero) { return 6; } }
+    if (max >= 7) { if (this.numeroProduction07 == numero) { return 7; } }
+    if (max >= 8) { if (this.numeroProduction08 == numero) { return 8; } }
+    if (max >= 9) { if (this.numeroProduction09 == numero) { return 9; } }
+    if (max >= 10) { if (this.numeroProduction10 == numero) { return 10; } }
+    
+    return 0;
+  }
+
+  public int getNumeroProduction(int place, int max)
+  {
+    if (max >= 1) { if (place == 1) { return this.numeroProduction01; } }
+    if (max >= 2) { if (place == 2) { return this.numeroProduction02; } }
+    if (max >= 3) { if (place == 3) { return this.numeroProduction03; } }
+    if (max >= 4) { if (place == 4) { return this.numeroProduction04; } }
+    if (max >= 5) { if (place == 5) { return this.numeroProduction05; } }
+    if (max >= 6) { if (place == 6) { return this.numeroProduction06; } }
+    if (max >= 7) { if (place == 7) { return this.numeroProduction07; } }
+    if (max >= 8) { if (place == 8) { return this.numeroProduction08; } }
+    if (max >= 9) { if (place == 9) { return this.numeroProduction09; } }
+    if (max >= 10) { if (place == 10) { return this.numeroProduction10; } }
+    
+    return 0;
+  }
+  
+  public void setFlagValide(boolean b) { this.flagValide = b; }
+  public boolean getFlagValide() { return this.flagValide; }
+  
+}

+ 1 - 1
src/main/java/fr/triplea/demovote/security/jwt/RefreshTokenService.java

@@ -35,7 +35,7 @@ public class RefreshTokenService
     refreshToken.setExpiryDate(Instant.now().plusMillis(refreshTokenDurationMs));
     refreshToken.setToken(UUID.randomUUID().toString());
 
-    refreshToken = refreshTokenRepository.save(refreshToken);
+    refreshToken = refreshTokenRepository.saveAndFlush(refreshToken);
     
     return refreshToken;
   }

+ 2 - 2
src/main/java/fr/triplea/demovote/web/client/WebcamsCache.java

@@ -123,7 +123,7 @@ public class WebcamsCache
       w.setCrc32(c32);
       w.setVue(b);
       
-      webcamRepository.save(w);
+      webcamRepository.saveAndFlush(w);
     }
     else 
     {
@@ -132,7 +132,7 @@ public class WebcamsCache
         w.setCrc32(c32);
         w.setVue(b);
 
-        webcamRepository.save(w);
+        webcamRepository.saveAndFlush(w);
       }
     }
   }

+ 2 - 2
src/main/java/fr/triplea/demovote/web/controller/AccountController.java

@@ -137,7 +137,7 @@ public class AccountController
          
         found.setCommentaire(participant.getCommentaire());
                
-        participantRepository.save(found);
+        participantRepository.saveAndFlush(found);
        
         MessagesTransfer mt = new MessagesTransfer();
         mt.setInformation(messageSource.getMessage("participant.updated", null, locale));
@@ -180,7 +180,7 @@ public class AccountController
           {
             found.setMotDePasse(passwordEncoder.encode(mdp_new.trim()));
             
-            participantRepository.save(found);
+            participantRepository.saveAndFlush(found);
 
             mdpt.setAncien("<success@old>");
             mdpt.setNouveau("<success@new>");

+ 331 - 76
src/main/java/fr/triplea/demovote/web/controller/BulletinController.java

@@ -1,14 +1,16 @@
 package fr.triplea.demovote.web.controller;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.MessageSource;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.security.core.Authentication;
+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.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
@@ -18,7 +20,10 @@ import fr.triplea.demovote.dao.BulletinRepository;
 import fr.triplea.demovote.dao.CategorieRepository;
 import fr.triplea.demovote.dao.ParticipantRepository;
 import fr.triplea.demovote.dao.ProductionRepository;
+import fr.triplea.demovote.dao.VariableRepository;
+import fr.triplea.demovote.dto.BulletinShort;
 import fr.triplea.demovote.dto.MessagesTransfer;
+import fr.triplea.demovote.dto.ProductionItem;
 import fr.triplea.demovote.model.Bulletin;
 import fr.triplea.demovote.model.Categorie;
 import fr.triplea.demovote.model.Participant;
@@ -30,7 +35,12 @@ import jakarta.servlet.http.HttpServletRequest;
 public class BulletinController 
 {
 
-  // TODO
+  // TODO : possibilités selon flags de la catégorie
+  // TODO : validation automatique des votes à la clôture du scrutin
+  // TODO : résultats
+  
+  @Autowired
+  private VariableRepository variableRepository;
 
   @Autowired
   private BulletinRepository bulletinRepository;
@@ -50,107 +60,352 @@ public class BulletinController
   @Autowired
   private MessageSource messageSource;
 
-  @PostMapping(value = "/create")
+
+  @GetMapping(value = "/count/{id}")
   @PreAuthorize("hasRole('USER')")
-  public ResponseEntity<Object> add(@RequestParam(required = true) int cat_id, @RequestParam(required = true) int part_id, @RequestParam(required = true) int prod_id, HttpServletRequest request) 
+  public ResponseEntity<Integer> remaining(@PathVariable("id") int numeroCategorie, final Authentication authentication, HttpServletRequest request) 
   { 
-    Locale locale = localeResolver.resolveLocale(request);
+    int numeroParticipant = this.getNumeroUser(authentication);
+    
+    BulletinShort bulletin = bulletinRepository.findByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
 
-    Bulletin bul = bulletinRepository.findByCategorieAndParticipant(cat_id, part_id);
+    int nombreMax = Math.max(1, Math.min(Integer.parseInt(variableRepository.findByTypeAndCode("Résultats", "NOMBRE_CHOIX")), 10));        
     
-    Categorie cat = categorieRepository.findById(cat_id);
-    Participant part = participantRepository.findById(part_id);
-    Production prod = productionRepository.findById(prod_id);
+    int nombreChoix = 0;
     
-    if (bul == null) 
+    if (bulletin != null) 
+    {
+      if (bulletin.getFlagValide())
+      {
+        nombreChoix = -1;
+      }
+      else 
+      {
+        int place = bulletin.getPlaceLibre(nombreMax);
+        
+        if (place > 0) { nombreChoix = (nombreMax - (place - 1)); }
+      }
+    }
+    else
+    {
+      Categorie categorie = categorieRepository.findById(numeroCategorie);
+
+      Participant participant = participantRepository.findById(numeroParticipant);
+      
+      if ((categorie != null) && (participant != null))
+      {
+        Bulletin nouveau = new Bulletin(); // création de l'enregistrement si absent
+        
+        nouveau.setCategorie(categorie);
+        nouveau.setParticipant(participant);
+        nouveau.setProduction01(null);
+        nouveau.setProduction02(null);
+        nouveau.setProduction03(null);
+        nouveau.setProduction04(null);
+        nouveau.setProduction05(null);
+        nouveau.setProduction06(null);
+        nouveau.setProduction07(null);
+        nouveau.setProduction08(null);
+        nouveau.setProduction09(null);
+        nouveau.setProduction10(null);
+        
+        bulletinRepository.saveAndFlush(nouveau);
+        
+        nombreChoix = nombreMax;
+      }
+    }
+
+    return ResponseEntity.ok(Integer.valueOf(nombreChoix));
+  }
+
+  
+  @GetMapping(value = "/list/{id}")
+  @PreAuthorize("hasRole('ADMIN')")
+  public List<ProductionItem> getChosenList(@PathVariable("id") int numeroCategorie, final Authentication authentication, HttpServletRequest request) 
+  {
+    int numeroParticipant = this.getNumeroUser(authentication);
+    
+    BulletinShort bulletin = bulletinRepository.findByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+    
+    List<ProductionItem> prods = new ArrayList<ProductionItem>();
+
+    if (bulletin != null) 
     { 
-      bul = new Bulletin();
+      int nombreMax = Math.max(1, Math.min(Integer.parseInt(variableRepository.findByTypeAndCode("Résultats", "NOMBRE_CHOIX")), 10));        
+
+      ProductionItem prod01 = (nombreMax >= 1) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction01()) : null;
+      ProductionItem prod02 = (nombreMax >= 2) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction02()) : null;
+      ProductionItem prod03 = (nombreMax >= 3) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction03()) : null;
+      ProductionItem prod04 = (nombreMax >= 4) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction04()) : null;
+      ProductionItem prod05 = (nombreMax >= 5) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction05()) : null;
+      ProductionItem prod06 = (nombreMax >= 6) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction06()) : null;
+      ProductionItem prod07 = (nombreMax >= 7) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction07()) : null;
+      ProductionItem prod08 = (nombreMax >= 8) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction08()) : null;
+      ProductionItem prod09 = (nombreMax >= 9) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction09()) : null;
+      ProductionItem prod10 = (nombreMax >= 10) ? productionRepository.findChosen(numeroCategorie, bulletin.getNumeroProduction10()) : null;
       
-      bul.setCategorie(cat); 
-      bul.setParticipant(part);
+      if ((prod01 != null) && (nombreMax >= 1)) { prods.add(prod01); }
+      if ((prod02 != null) && (nombreMax >= 2)) { prods.add(prod02); }
+      if ((prod03 != null) && (nombreMax >= 3)) { prods.add(prod03); }
+      if ((prod04 != null) && (nombreMax >= 4)) { prods.add(prod04); }
+      if ((prod05 != null) && (nombreMax >= 5)) { prods.add(prod05); }
+      if ((prod06 != null) && (nombreMax >= 6)) { prods.add(prod06); }
+      if ((prod07 != null) && (nombreMax >= 7)) { prods.add(prod07); }
+      if ((prod08 != null) && (nombreMax >= 8)) { prods.add(prod08); }
+      if ((prod09 != null) && (nombreMax >= 9)) { prods.add(prod09); }
+      if ((prod10 != null) && (nombreMax >= 10)) { prods.add(prod10); }
     }
+
+    return prods;
+  }
+  
+  
+  @GetMapping(value = "/choose")
+  @PreAuthorize("hasRole('USER')")
+  public ResponseEntity<Object> chooseProduction(@RequestParam("id_cat") int numeroCategorie, @RequestParam("id_prod") int numeroProduction, final Authentication authentication, HttpServletRequest request) 
+  {
+    Locale locale = localeResolver.resolveLocale(request);
+
+    int numeroParticipant = this.getNumeroUser(authentication);
+    
+    BulletinShort bulletin = bulletinRepository.findByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
     
-    if (bul != null) 
+    Production production = productionRepository.findByIdLinkedByCategorie(numeroCategorie, numeroProduction);
+    
+    if ((bulletin != null) && (production != null)) 
     { 
-      Production prod01 = bul.getProduction01();
+      int nombreMax = Math.max(1, Math.min(Integer.parseInt(variableRepository.findByTypeAndCode("Résultats", "NOMBRE_CHOIX")), 10));        
 
-      if (prod01 == null) { bul.setProduction01(prod); }
-      else
+      boolean existe = (bulletin.getPlace(numeroProduction, nombreMax) > 0);
+      
+      if (!existe)
       {
-        Production prod02 = bul.getProduction02();
-
-        if (prod02 == null) { bul.setProduction02(prod); }
-        else
+        int place = bulletin.getPlaceLibre(nombreMax);
+        
+        if (place > 0)
         {
-          Production prod03 = bul.getProduction03();
+          Bulletin vote = bulletinRepository.getByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
 
-          if (prod03 == null) { bul.setProduction03(prod); }
-          else
+          switch (place)
           {
-            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); }
-                      }
-                    }
-                  }
-                }
-              } 
-            }
+            case 1: vote.setProduction01(production); break;
+            case 2: vote.setProduction02(production); break;
+            case 3: vote.setProduction03(production); break;
+            case 4: vote.setProduction04(production); break;
+            case 5: vote.setProduction05(production); break;
+            case 6: vote.setProduction06(production); break;
+            case 7: vote.setProduction07(production); break;
+            case 8: vote.setProduction08(production); break;
+            case 9: vote.setProduction09(production); break;
+            case 10: vote.setProduction10(production); break;
           }
+          
+          bulletinRepository.saveAndFlush(vote);          
+
+          MessagesTransfer mt = new MessagesTransfer();
+          mt.setInformation(messageSource.getMessage("vote.chosen", null, locale));
+
+          return ResponseEntity.ok(mt);
         }
       }
+    }
+     
+    return ResponseEntity.notFound().build(); 
+  }
+
+  @GetMapping(value = "/discard")
+  @PreAuthorize("hasRole('USER')")
+  public ResponseEntity<Object> discardProduction(@RequestParam("id_cat") int numeroCategorie, @RequestParam("id_prod") int numeroProduction, final Authentication authentication, HttpServletRequest request) 
+  {
+    Locale locale = localeResolver.resolveLocale(request);
+
+    int numeroParticipant = this.getNumeroUser(authentication);
+        
+    BulletinShort bulletin = bulletinRepository.findByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+
+    Production production = productionRepository.findByIdLinkedByCategorie(numeroCategorie, numeroProduction);
+    
+    if ((bulletin != null) && (production != null)) 
+    { 
+      int nombreMax = Math.max(1, Math.min(Integer.parseInt(variableRepository.findByTypeAndCode("Résultats", "NOMBRE_CHOIX")), 10));        
+
+      int place = bulletin.getPlace(numeroProduction, nombreMax);
       
-      bulletinRepository.saveAndFlush(bul); 
+      if (place > 0)
+      {
+        Bulletin vote = bulletinRepository.getByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+
+        switch (place) // pas de break; pour continuer les décalages jusqu'à la place 10
+        {
+          case 1: vote.setProduction01(vote.getProduction02()); 
+          case 2: vote.setProduction02(vote.getProduction03()); 
+          case 3: vote.setProduction03(vote.getProduction04()); 
+          case 4: vote.setProduction04(vote.getProduction05()); 
+          case 5: vote.setProduction05(vote.getProduction06()); 
+          case 6: vote.setProduction06(vote.getProduction07()); 
+          case 7: vote.setProduction07(vote.getProduction08()); 
+          case 8: vote.setProduction08(vote.getProduction09()); 
+          case 9: vote.setProduction09(vote.getProduction10()); 
+          case 10: vote.setProduction10(null); 
+        }
+        
+        bulletinRepository.saveAndFlush(vote);          
+        
+        MessagesTransfer mt = new MessagesTransfer();
+        mt.setInformation(messageSource.getMessage("vote.discarded", null, locale));
+
+        return ResponseEntity.ok(mt);
+      }
     }
-   
-    MessagesTransfer mt = new MessagesTransfer();
-    mt.setInformation(messageSource.getMessage("bulletin.inserted", null, locale));
+     
+    return ResponseEntity.notFound().build(); 
+  }
 
-    return ResponseEntity.ok(mt);
+  @GetMapping(value = "/up")
+  @PreAuthorize("hasRole('USER')")
+  public ResponseEntity<Object> avancerProduction(@RequestParam("id_cat") int numeroCategorie, @RequestParam("id_prod") int numeroProduction, final Authentication authentication, HttpServletRequest request) 
+  {
+    Locale locale = localeResolver.resolveLocale(request);
+
+    int numeroParticipant = this.getNumeroUser(authentication);
+    
+    BulletinShort bulletin = bulletinRepository.findByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+    
+    Production production = productionRepository.findByIdLinkedByCategorie(numeroCategorie, numeroProduction);
+    
+    if ((bulletin != null) && (production != null)) 
+    { 
+      int nombreMax = Math.max(1, Math.min(Integer.parseInt(variableRepository.findByTypeAndCode("Résultats", "NOMBRE_CHOIX")), 10));        
+
+      int place = bulletin.getPlace(numeroProduction, nombreMax);
+      
+      if (place > 1)
+      {
+        Production precedent = productionRepository.findByIdLinkedByCategorie(numeroCategorie, bulletin.getNumeroProduction(place - 1, nombreMax));
+
+        Bulletin vote = bulletinRepository.getByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+        
+        switch (place)
+        {
+          case 2: vote.setProduction01(production); vote.setProduction02(precedent); break;
+          case 3: vote.setProduction02(production); vote.setProduction03(precedent); break;
+          case 4: vote.setProduction03(production); vote.setProduction04(precedent); break;
+          case 5: vote.setProduction04(production); vote.setProduction05(precedent); break;
+          case 6: vote.setProduction05(production); vote.setProduction06(precedent); break;
+          case 7: vote.setProduction06(production); vote.setProduction07(precedent); break;
+          case 8: vote.setProduction07(production); vote.setProduction08(precedent); break;
+          case 9: vote.setProduction08(production); vote.setProduction09(precedent); break;
+          case 10: vote.setProduction09(production); vote.setProduction10(precedent); break;
+        }
+        
+        bulletinRepository.saveAndFlush(vote);          
+      }
+      
+      MessagesTransfer mt = new MessagesTransfer();
+      mt.setInformation(messageSource.getMessage("vote.topped", null, locale));
+
+      return ResponseEntity.ok(mt);
+    }
+     
+    return ResponseEntity.notFound().build(); 
   }
 
-  @DeleteMapping(value = "/delete/{id}")
+  @GetMapping(value = "/down")
   @PreAuthorize("hasRole('USER')")
-  public ResponseEntity<Object> remove(@PathVariable int id, HttpServletRequest request) 
-  { 
+  public ResponseEntity<Object> reculerProduction(@RequestParam("id_cat") int numeroCategorie, @RequestParam("id_prod") int numeroProduction, final Authentication authentication, HttpServletRequest request) 
+  {
     Locale locale = localeResolver.resolveLocale(request);
 
-    if (id > 0) { bulletinRepository.deleteById(id); } 
+    int numeroParticipant = this.getNumeroUser(authentication);
     
-    MessagesTransfer mt = new MessagesTransfer();
-    mt.setInformation(messageSource.getMessage("bulletin.deleted", null, locale));
+    BulletinShort bulletin = bulletinRepository.findByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+    
+    Production production = productionRepository.findByIdLinkedByCategorie(numeroCategorie, numeroProduction);
+    
+    if ((bulletin != null) && (production != null)) 
+    { 
+      int nombreMax = Math.max(1, Math.min(Integer.parseInt(variableRepository.findByTypeAndCode("Résultats", "NOMBRE_CHOIX")), 10));        
 
-    return ResponseEntity.ok(mt);
+      int place = bulletin.getPlace(numeroProduction, nombreMax);
+      
+      if (place < nombreMax)
+      {
+        Production suivant = productionRepository.findByIdLinkedByCategorie(numeroCategorie, bulletin.getNumeroProduction(place + 1, nombreMax));
+
+        Bulletin vote = bulletinRepository.getByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+        
+        switch (place)
+        {
+          case 1: vote.setProduction01(suivant); vote.setProduction02(production); break;
+          case 2: vote.setProduction02(suivant); vote.setProduction03(production); break;
+          case 3: vote.setProduction03(suivant); vote.setProduction04(production); break;
+          case 4: vote.setProduction04(suivant); vote.setProduction05(production); break;
+          case 5: vote.setProduction05(suivant); vote.setProduction06(production); break;
+          case 6: vote.setProduction06(suivant); vote.setProduction07(production); break;
+          case 7: vote.setProduction07(suivant); vote.setProduction08(production); break;
+          case 8: vote.setProduction08(suivant); vote.setProduction09(production); break;
+          case 9: vote.setProduction09(suivant); vote.setProduction10(production); break;
+        }
+        
+        bulletinRepository.saveAndFlush(vote);          
+      }
+
+      MessagesTransfer mt = new MessagesTransfer();
+      mt.setInformation(messageSource.getMessage("vote.bottomed", null, locale));
+
+      return ResponseEntity.ok(mt);
+    }
+     
+    return ResponseEntity.notFound().build(); 
+  }
+
+
+  @GetMapping(value = "/validate/{id}")
+  @PreAuthorize("hasRole('USER')")
+  public ResponseEntity<Object> validerVote(@PathVariable("id") int numeroCategorie, final Authentication authentication, HttpServletRequest request) 
+  {
+    Locale locale = localeResolver.resolveLocale(request);
+
+    int numeroParticipant = this.getNumeroUser(authentication);
+    
+    Bulletin bulletin = bulletinRepository.getByCategorieAndParticipant(numeroCategorie, numeroParticipant); 
+   
+    if ((bulletin != null)) 
+    { 
+      if (bulletin.getProduction01() != null) // au moins une production choisie pour valider
+      {
+        bulletin.setConfirmed(true);
+        
+        bulletinRepository.saveAndFlush(bulletin);          
+        
+        MessagesTransfer mt = new MessagesTransfer();
+        mt.setInformation(messageSource.getMessage("vote.validated", null, locale));
+
+        return ResponseEntity.ok(mt);
+      }
+    }
+     
+    return ResponseEntity.notFound().build(); 
   }
 
+
+  /** retourne le numéro identifiant du participant */
+  private final int getNumeroUser(Authentication auth)
+  {
+    int numeroParticipant = -1; // -1 pour non trouvé
+    
+    if (auth != null)
+    {
+      Participant found = participantRepository.findByPseudonyme(auth.getName());
+      
+      if (found != null)
+      {
+        numeroParticipant = found.getNumeroParticipant();
+      }
+    }
+    
+    return numeroParticipant;
+  }
+
+
 }

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

@@ -75,7 +75,7 @@ public class CategorieController
     
     if (categorie.hasLibelle()) 
     { 
-      categorieRepository.save(categorie); 
+      categorieRepository.saveAndFlush(categorie); 
      
       MessagesTransfer mt = new MessagesTransfer();
       mt.setInformation(messageSource.getMessage("categorie.created", null, locale));
@@ -106,7 +106,7 @@ public class CategorieController
       found.setPollable(categorie.isPollable());
       found.setComputed(categorie.isComputed());
 
-      categorieRepository.save(found); 
+      categorieRepository.saveAndFlush(found); 
       
       MessagesTransfer mt = new MessagesTransfer();
       mt.setInformation(messageSource.getMessage("categorie.updated", null, locale));

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

@@ -103,7 +103,7 @@ public class MessageController
           
           if (destinataire != null) { m.setDestinataire(destinataire); } else { m.setDestinataire(null); }
           
-          messageRepository.save(m);
+          messageRepository.saveAndFlush(m);
         }
         
         mlist = messageRepository.findNew(found.getNumeroParticipant(), last);

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

@@ -247,7 +247,7 @@ public class ParticipantController
             if (userRole != null) { found.setRoles(Arrays.asList(userRole)); }
           }
                     
-          participantRepository.save(found);
+          participantRepository.saveAndFlush(found);
           
           MessagesTransfer mt = new MessagesTransfer();
           mt.setInformation(messageSource.getMessage("participant.created", null, locale));
@@ -345,7 +345,7 @@ public class ParticipantController
         if (userRole != null) { found.setRoles(Arrays.asList(userRole)); }
       }
 
-      participantRepository.save(found);
+      participantRepository.saveAndFlush(found);
       
       MessagesTransfer mt = new MessagesTransfer();
       mt.setInformation(messageSource.getMessage("participant.updated", null, locale));

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

@@ -22,7 +22,7 @@ import fr.triplea.demovote.model.Preference;
 public class PreferenceController 
 {
 
-  // TODO
+  // TODO ?
 
   @Autowired
   private PreferenceRepository preferenceRepository;
@@ -43,7 +43,7 @@ public class PreferenceController
 
     if (found == null) { preference.setNumeroPreference(null); }
     
-    return  preferenceRepository.save(preference);
+    return  preferenceRepository.saveAndFlush(preference);
   }
 
   @PutMapping(value = "/update/{id}")
@@ -58,7 +58,7 @@ public class PreferenceController
       found.setNumeroTraitement(preference.getNumeroTraitement());
       found.setValeurs(preference.getValeurs());
       
-      preferenceRepository.save(found);
+      preferenceRepository.saveAndFlush(found);
     
       return ResponseEntity.ok(found);
     }

+ 7 - 3
src/main/java/fr/triplea/demovote/web/controller/PresentationController.java

@@ -426,7 +426,7 @@ public class PresentationController
           presentation.setNombrePoints(0);
           presentation.setNombrePolePosition(0);
           
-          presentationRepository.save(presentation);
+          presentationRepository.saveAndFlush(presentation);
               
           MessagesTransfer mt = new MessagesTransfer();
           mt.setInformation(messageSource.getMessage("production.linked", null, locale));
@@ -507,6 +507,7 @@ public class PresentationController
                   
                   presentationRepository.save(presentations.get(i - 1));
                   presentationRepository.save(presentations.get(i));
+                  presentationRepository.flush();
                   
                   break;
                 }
@@ -560,6 +561,7 @@ public class PresentationController
                 
                 presentationRepository.save(presentations.get(i));
                 presentationRepository.save(presentations.get(i + 1));
+                presentationRepository.flush();
                 
                 break;
               }
@@ -608,7 +610,9 @@ public class PresentationController
       {
         int etat = presentation.etatMedia();
         String nom = presentation.mediaName();
-         
+        
+        // TODO : réinitialiser l'état si une nouvelle archive a été uploadé au niveau de la production
+        
         if (presentation.mediaData() == null) { etat = 0; }
         
         MessagesTransfer mt = new MessagesTransfer();
@@ -632,7 +636,7 @@ public class PresentationController
           break;
         }
 
-        presentationRepository.save(found);
+        presentationRepository.saveAndFlush(found);
 
         return ResponseEntity.ok(mt);
       }

+ 15 - 4
src/main/java/fr/triplea/demovote/web/controller/ProductionController.java

@@ -37,6 +37,7 @@ import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.servlet.LocaleResolver;
 
 import fr.triplea.demovote.dao.ParticipantRepository;
+import fr.triplea.demovote.dao.PresentationRepository;
 import fr.triplea.demovote.dao.ProductionRepository;
 import fr.triplea.demovote.dto.MessagesTransfer;
 import fr.triplea.demovote.dto.ProductionFile;
@@ -44,6 +45,7 @@ import fr.triplea.demovote.dto.ProductionShort;
 import fr.triplea.demovote.dto.ProductionTransfer;
 import fr.triplea.demovote.dto.ProductionUpdate;
 import fr.triplea.demovote.model.Participant;
+import fr.triplea.demovote.model.Presentation;
 import fr.triplea.demovote.model.Production;
 import fr.triplea.demovote.model.ProductionType;
 import io.hypersistence.utils.hibernate.type.basic.Inet;
@@ -59,6 +61,9 @@ public class ProductionController
   
   @Autowired
   private ProductionRepository productionRepository;
+  
+  @Autowired
+  private PresentationRepository presentationRepository;
 
   @Autowired
   private ParticipantRepository participantRepository;
@@ -204,7 +209,7 @@ public class ProductionController
 
       fresh.setVignette(production.vignette());
       
-      productionRepository.save(fresh);
+      productionRepository.saveAndFlush(fresh);
 
       return ResponseEntity.ok(Integer.valueOf(fresh.getNumeroProduction()));
     }
@@ -251,7 +256,7 @@ public class ProductionController
       
           if (production.vignette() != null) { if (!(production.vignette().isBlank())) { found.setVignette(production.vignette()); } }
           
-          productionRepository.save(found);
+          productionRepository.saveAndFlush(found);
           
           MessagesTransfer mt = new MessagesTransfer();
           mt.setInformation(messageSource.getMessage("production.updated", null, locale));
@@ -408,7 +413,7 @@ public class ProductionController
           LOG.error(messageSource.getMessage("chunk.count.failed", new Object[] { fileName, lastChunkIndex, dir.listFiles().length }, locale)); 
         }
 
-        productionRepository.save(found);
+        productionRepository.saveAndFlush(found);
 
         if (succes) { dir.delete(); }
         
@@ -436,10 +441,16 @@ public class ProductionController
 
       if ((numeroUser == 0) || (found.getParticipant().getNumeroParticipant() == numeroUser))
       {
+        // TODO : pas de suppression logique si présence dans les bulletins
+        
         found.setEnabled(false); 
         
         productionRepository.saveAndFlush(found);
-             
+ 
+        Presentation presente = presentationRepository.findByProduction(id);
+        
+        if (presente != null) { presentationRepository.delete(presente); }
+        
         MessagesTransfer mt = new MessagesTransfer();
         mt.setInformation(messageSource.getMessage("production.deleted", null, locale));
 

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

@@ -78,7 +78,7 @@ public class VariableController
     
     if (variable.hasType() && variable.hasCode()) 
     { 
-      variableRepository.save(variable); 
+      variableRepository.saveAndFlush(variable); 
       
       MessagesTransfer mt = new MessagesTransfer();
       mt.setInformation(messageSource.getMessage("variable.created", null, locale));
@@ -104,7 +104,7 @@ public class VariableController
       found.setValeur(variable.getValeur());
       found.setNotes(variable.getNotes());
       
-      variableRepository.save(found);
+      variableRepository.saveAndFlush(found);
       
       MessagesTransfer mt = new MessagesTransfer();
       mt.setInformation(messageSource.getMessage("variable.updated", null, locale));

+ 6 - 0
src/main/resources/langs/messages_en.properties

@@ -60,3 +60,9 @@ chunk.merged.success=Succes uploading file {0}.
 chunk.merged.failed=Failure uploading file {0}.
 chunk.count.failed=Count error on {0} file parts (expected: {1}, seen: {2}).
 chunk.checksum.failed=Failure checking with MD5 hashing on {0} file (expected: {1}, computed: {2}).
+
+vote.chosen=This production was chosen.
+vote.discarded=This production was discarded.
+vote.topped=This production was topped in your choices.
+vote.bottomed=This production was bottomed in your choices.
+vote.validated=Choices are validated/locked for this compo.

+ 6 - 0
src/main/resources/langs/messages_fr.properties

@@ -60,3 +60,9 @@ chunk.merged.success=Succ
 chunk.merged.failed=Echec pour le téléversement fichier {0}.
 chunk.count.failed=Décompte erroné pour les parties du fichier {0} (attendu: {1}, vu: {2}).
 chunk.checksum.failed=Echec de la vérification par hachage MD5 du fichier {0} (attendu: {1}, calculé: {2}).
+
+vote.chosen=La production a été choisie.
+vote.discarded=La production a été écartée.
+vote.topped=La production a été avancée dans vos choix.
+vote.bottomed=La production a été reculée dans vos choix.
+vote.validated=Les choix ont été validés/gelés dans cette catégorie.