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  }