github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/vote/vote.go (about) 1 package vote 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/benoitkugler/goACVE/server/core/rawdata" 8 "github.com/benoitkugler/goACVE/server/shared" 9 ) 10 11 // --------------------- page de vote ---------------------------- 12 13 func (ct Controller) getPersonneMeta(id int64) (MetaPersonne, error) { 14 row := ct.db.QueryRow("SELECT * FROM personnes WHERE id = $1", id) 15 pers, err := rawdata.ScanPersonne(row) 16 if err != nil { 17 return MetaPersonne{}, err 18 } 19 return MetaPersonne{PrenomNom: pers.NomPrenom().String()}, nil 20 } 21 22 func (ct Controller) getStatutPersonne(idPersonne int64) ([]VotePersonneComplet, error) { 23 votes, err := ct.getVotes() 24 if err != nil { 25 return nil, err 26 } 27 28 votesDone, err := SelectVotePersonneByIdPersonne(ct.db, idPersonne) 29 if err != nil { 30 return nil, err 31 } 32 // par id vote 33 votesDoneMap := make(map[int64]VotePersonne) 34 for _, vp := range votesDone { 35 votesDoneMap[vp.IdVote] = vp 36 } 37 38 // on ajoute les choix courants de la personne 39 allChoix, err := SelectVotePersonneCandidatByIdPersonne(ct.db, idPersonne) 40 if err != nil { 41 return nil, err 42 } 43 // on répartis les choix candidats par candidats 44 tmp := make(map[int64]Ids) // id vote -> candidats 45 for _, choix := range allChoix { 46 tmp[choix.IdVote] = append(tmp[choix.IdVote], choix.IdCandidat) 47 } 48 // puis on copie dans les votes 49 out := make([]VotePersonneComplet, len(votes)) 50 for i, v := range votes { 51 out[i] = VotePersonneComplet{VoteCandidats: v, Time: votesDoneMap[v.Id].Time, Choix: tmp[v.Id]} 52 } 53 54 return out, nil 55 } 56 57 // champs pertinents : idVote et choix 58 func (ct Controller) effectueVote(idPersonne int64, vote VotePersonneComplet) error { 59 var err error 60 vote.Vote, err = SelectVote(ct.db, vote.Id) 61 if err != nil { 62 return err 63 } 64 if vote.IsLocked { 65 return fmt.Errorf("Ce vote est maintenant clos.") 66 } 67 if !vote.Vote.IsQCM && len(vote.Choix) > 1 { 68 return fmt.Errorf("Ce vote n'accepte pas de choix multiple.") 69 } 70 71 // on vérifie si les candidats donnés sont valides : 72 // en cas de modification du vote, des candidats "périmés" 73 // pourrait facilement arriver 74 rows, err := ct.db.Query("SELECT * FROM candidats WHERE id_vote = $1", vote.Id) 75 if err != nil { 76 return err 77 } 78 validCandidats, err := ScanCandidats(rows) 79 if err != nil { 80 return err 81 } 82 83 var vps VotePersonneCandidats 84 for _, choix := range vote.Choix { 85 if _, ok := validCandidats[choix]; !ok { 86 return fmt.Errorf("Il semble que le vote soit périmé. Merci de rafraichir les votes.") 87 } 88 vps = append(vps, VotePersonneCandidat{IdPersonne: idPersonne, IdVote: vote.Id, IdCandidat: choix}) 89 } 90 91 tx, err := ct.db.Begin() 92 if err != nil { 93 return err 94 } 95 // on remet à zéro les choix pour ce vote ... 96 _, err = tx.Exec("DELETE FROM vote_personne_candidats WHERE id_personne = $1 AND id_vote = $2", idPersonne, vote.Id) 97 if err != nil { 98 return shared.Rollback(tx, err) 99 } 100 _, err = tx.Exec("DELETE FROM vote_personnes WHERE id_personne = $1 AND id_vote = $2", idPersonne, vote.Id) 101 if err != nil { 102 return shared.Rollback(tx, err) 103 } 104 105 // ... et on inscrits les nouveaux 106 err = InsertManyVotePersonnes(tx, VotePersonne{IdPersonne: idPersonne, IdVote: vote.Id, Time: time.Now()}) 107 if err != nil { 108 return shared.Rollback(tx, err) 109 } 110 111 err = InsertManyVotePersonneCandidats(tx, vps...) 112 if err != nil { 113 return shared.Rollback(tx, err) 114 } 115 return tx.Commit() 116 } 117 118 func (ct Controller) resetVotePersonne(idPersonne, idVote int64) error { 119 vote, err := SelectVote(ct.db, idVote) 120 if err != nil { 121 return err 122 } 123 if vote.IsLocked { 124 return fmt.Errorf("Ce vote est maintenant clos.") 125 } 126 127 tx, err := ct.db.Begin() 128 if err != nil { 129 return err 130 } 131 // liens 132 _, err = tx.Exec("DELETE FROM vote_personne_candidats WHERE id_personne = $1 AND id_vote = $2", idPersonne, idVote) 133 if err != nil { 134 return shared.Rollback(tx, err) 135 } 136 _, err = tx.Exec("DELETE FROM vote_personnes WHERE id_personne = $1 AND id_vote = $2", idPersonne, idVote) 137 if err != nil { 138 return shared.Rollback(tx, err) 139 } 140 return tx.Commit() 141 } 142 143 func (ct Controller) exportBilanPersonne(idPersonne int64) (MetaPersonne, []byte, error) { 144 membre, err := ct.getPersonneMeta(idPersonne) 145 if err != nil { 146 return membre, nil, err 147 } 148 votes, err := ct.getStatutPersonne(idPersonne) 149 if err != nil { 150 return membre, nil, err 151 } 152 out, err := genereBilanPersonne(membre, votes) 153 return membre, out, err 154 }