diff --git a/internal/models/models.go b/internal/models/models.go index 2a480833836204ee1a199eb7e0bb09296f02c8b0..32dc7df0f5b6e8b96c98b5831496416a798bda6f 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -41,6 +41,9 @@ const ErrorValidateVote = "Error in the process to validate a vote" // ErrorVoteExist = "Error the vote have already been captured" with 500 http.StatusInternalServerError const ErrorVoteExist = "Error the vote have already been captured" +// ErrorValidatedVote = "Error the vote have already been validated and can't be updated" with 500 http.StatusInternalServerError +const ErrorValidatedVote = "Error the vote have already been validated and can't be updated" + // Election represent an election divided in areas with 1 or several rounds type Election struct { ID uint `gorm:"primary_key"` diff --git a/internal/models/vote.go b/internal/models/vote.go index 32a0fd6d345d747fd18d9e2fc4d18ee2c2e5cfb5..c9446676406ef1a810cdcd5405f1f51c590cb6ae 100644 --- a/internal/models/vote.go +++ b/internal/models/vote.go @@ -105,6 +105,10 @@ func (d *DataHandler) postVote(w http.ResponseWriter, r *http.Request) { http.Error(w, ErrorParentNotFound, http.StatusInternalServerError) return } + if deskRound.Validated { + http.Error(w, ErrorValidatedVote, http.StatusInternalServerError) + return + } d.db.Create(&o) d.db.Last(&o) @@ -120,6 +124,16 @@ func (d *DataHandler) putVote(w http.ResponseWriter, r *http.Request) { return } + var deskRound DeskRound + if err := d.db.First(&deskRound, vote.DeskRoundID).Error; err != nil { + http.Error(w, ErrorParentNotFound, http.StatusNotFound) + return + } + if deskRound.Validated { + http.Error(w, ErrorValidatedVote, http.StatusInternalServerError) + return + } + var o Vote if vote.Blank { if err := d.db.Where("blank = true and desk_round_id = ?", vote.DeskRoundID).Find(&o).Error; err != nil { @@ -151,17 +165,22 @@ func (d *DataHandler) deleteVote(w http.ResponseWriter, r *http.Request, id int) http.Error(w, ErrorIDIsMissing, http.StatusNotFound) return } - d.db.Delete(&o) - // Set completed to false for deskRound + // Set completed to false for deskRound if deskRound is not validated var deskRound DeskRound if err := d.db.First(&deskRound, o.DeskRoundID).Error; err != nil { http.Error(w, ErrorParentNotFound, http.StatusNotFound) return } + if deskRound.Validated { + http.Error(w, ErrorValidatedVote, http.StatusInternalServerError) + return + } deskRound.Completed = false d.db.Save(&deskRound) + d.db.Delete(&o) + } else { http.Error(w, ErrorIDIsMissing, http.StatusNotFound) } diff --git a/internal/rootmux/admin_test.go b/internal/rootmux/admin_test.go index 5e8fba7ceb6a1b715c879a8e96e2dad54d35a55b..49113d4ec523536ff26ea9f0f864dae4fda46f3c 100644 --- a/internal/rootmux/admin_test.go +++ b/internal/rootmux/admin_test.go @@ -126,8 +126,6 @@ func AdminTests(t *testing.T) { // Update a Vote do("PUT", "/api/Vote/1", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":false}`, 200, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":false}`) - // TODO Update a DeskRound to Validated=true can only be done when votes are captured - // Delete a Vote do("DELETE", "/api/Vote/1", xsrfHeader, ``, 200, ``) // Delete a Candidate diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go index 2d3d47c985699f2b24197f306eb4f7b8275111ff..c9f2ba9d5d758fbde5fc7ab2edebf4e5a8a6c2df 100644 --- a/internal/rootmux/rootmux_test.go +++ b/internal/rootmux/rootmux_test.go @@ -121,7 +121,15 @@ func appTests(t *testing.T) { do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":3,"Blank":true}`, 500, `Error the vote have already been captured`) do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":5,"NullVote":true}`, 500, `Error the vote have already been captured`) - //Check that on Vote deletion, deskRound is updated + // Update a DeskRound to Validated=true can only be done when votes are captured + do("PUT", "/api/DeskRound/1", xsrfHeader, `{"ID":1,"Validated":true}`, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":true,"DateCompletion":"20`) + + // If DeskRound is validated, votes can't be updated or deleted + do("PUT", "/api/Vote/1", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":358,"Blank":false,"NullVote":false}`, 500, `Error the vote have already been validated and can't be updated`) + do("DELETE", "/api/Vote/1", xsrfHeader, ``, 500, `Error the vote have already been validated and can't be updated`) + + // //Check that on Vote deletion, deskRound is updated + do("PUT", "/api/DeskRound/1", xsrfHeader, `{"ID":1,"Validated":false}`, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":true,"DateCompletion":"20`) do("DELETE", "/api/Vote/1", xsrfHeader, ``, 200, ``) do("GET", "/api/DeskRound/1", xsrfHeader, ``, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"20`) diff --git a/web/components/management/round-desks.js b/web/components/management/round-desks.js index 08c5de7af67e43e0b0da9af47077545e6cf39fa7..aaabb5ae1621fd045cb2beefa8877b3f7089985e 100644 --- a/web/components/management/round-desks.js +++ b/web/components/management/round-desks.js @@ -217,7 +217,6 @@ class RoundDesk { deskRound.ID ); deskRoundHandler.displayDeskRoundsDetails(); - deskRoundHandler.displayVotes(deskRound); }); document .getElementById(`deskrounds-deskround-capturers-${deskRound.ID}`) @@ -238,6 +237,7 @@ class RoundDesk { .addEventListener("click", async function () { await deskRoundHandler.saveDeskRound(); }); + deskRoundHandler.displayVotes(this.deskRound); } async activateDeskRound(deskRoundToActivate) { @@ -262,7 +262,7 @@ class RoundDesk { async saveDeskRound() { try { - this.DeskRoundModel.saveDeskRound( + this.deskRound = await this.DeskRoundModel.saveDeskRound( this.deskRound.ID, document.getElementById("deskround-validated").checked ); @@ -271,7 +271,9 @@ class RoundDesk { console.error(e); return; } - this.displayDesks(); + await this.displayDesks(); + await this.activateDeskRound(this.deskRound); + await this.refreshVotes(); } async refreshCapturers() { @@ -339,7 +341,7 @@ class RoundDesk { this.desk = null; document.getElementById("desk-round-details").innerHTML = ""; document.getElementById("vote-section").innerHTML = ""; - document.getElementById("vote-section").classList = "" + document.getElementById("vote-section").classList = ""; } async displayVotes(deskRound) { diff --git a/web/components/vote/votes.js b/web/components/vote/votes.js index 45aa32dd642009a19aacf82c8bcbdedc91b6ae29..73ac0579971e983d582ac8df15288e88c0977ad3 100644 --- a/web/components/vote/votes.js +++ b/web/components/vote/votes.js @@ -52,7 +52,7 @@ class Vote { </header> <div id="votes-table"></div> <nav class="level"> - <div class="level-left"><p id="total-votes"></p>, <p id="votes-expressed"></p></div> + <div class="level-left" id="votes-stats"></div> <div class="level-right"> <button id="votes-return" class="button level-item"> Retour @@ -73,6 +73,24 @@ class Vote { await this.refreshBreadCrumb(); await this.loadVotes(); + + let deskRound = await this.DeskRoundModel.getDeskRound(this.DeskRoundID); + if (deskRound.Validated) { + document.getElementById("votes-table").innerHTML = /* HTML */ `<article + class="message is-warning" + > + <div class="message-header"> + <p>Votes validés</p> + </div> + <div class="message-body"> + Les votes ont étaient validés et ne peuvent plus être modifiés + </div> + </article>`; + document.getElementById("votes-stats").innerHTML = ""; + document.getElementById(`votes-cancel`).setAttribute("disabled", "true"); + document.getElementById(`votes-save`).setAttribute("disabled", "true"); + document.getElementById(`votes-delete`).setAttribute("disabled", "true"); + } } voteTemplate(candidateList) { @@ -204,10 +222,11 @@ class Vote { vote.VoiceNumber; } }); - document.getElementById("total-votes").innerHTML = - "Suffrages total : " + totalVotes; - document.getElementById("votes-expressed").innerHTML = - "Suffrages exprimés : " + votesExpressed; + document.getElementById("votes-stats").innerHTML = + "Suffrages total : " + + totalVotes + + ", Suffrages exprimés : " + + votesExpressed; } async saveVotes() {