github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/core/rawdata/composites/participants.go (about)

     1  package composites
     2  
     3  import (
     4  	"fmt"
     5  
     6  	rd "github.com/benoitkugler/goACVE/server/core/rawdata"
     7  )
     8  
     9  func (ps ParticipantPersonnes) LoadCamps(db rd.DB) (ParticipantCamps, error) {
    10  	s := rd.NewSet()
    11  	for _, p := range ps {
    12  		s.Add(p.Participant.Id)
    13  	}
    14  	rows, err := db.Query(`SELECT participants.*, camps.* FROM participants
    15  		JOIN camps ON participants.id_camp = camps.id
    16  		WHERE participants.id = ANY ($1)`, rd.Ids(s.Keys()).AsSQL())
    17  	if err != nil {
    18  		return nil, err
    19  	}
    20  	return ScanParticipantCamps(rows)
    21  }
    22  
    23  // LookupToPersonnes renvoie l'association idParticipant -> personne
    24  func (ps ParticipantPersonnes) LookupToPersonnes() rd.Personnes {
    25  	out := make(rd.Personnes, len(ps))
    26  	for _, v := range ps {
    27  		out[v.Participant.Id] = v.Personne
    28  	}
    29  	return out
    30  }
    31  
    32  // OptionParticipantCamp suffit à déterminer
    33  // les dates de présence d'un participant et d'autres quantités liées
    34  type OptionParticipantCamp struct {
    35  	OptionPrix rd.OptionPrixParticipant
    36  	Camp       rd.Camp
    37  }
    38  
    39  func (pc ParticipantCamp) AsOptionParticipantCamp() OptionParticipantCamp {
    40  	return OptionParticipantCamp{OptionPrix: pc.Participant.OptionPrix, Camp: pc.Camp}
    41  }
    42  
    43  // met à jour si candidat n'est pas zero
    44  func safeChange(date, candidat rd.Date) rd.Date {
    45  	if !candidat.Time().IsZero() {
    46  		return candidat
    47  	}
    48  	return date
    49  }
    50  
    51  // NbJours renvoie la de présence du participant
    52  // en prenant en compte une éventulle option SEMAINE ou JOUR.
    53  // et indique s'il s'agit du cas particulier JOUR.
    54  // Pour un camp avec option JOUR, il peut s'agir d'une approximation.
    55  func (p OptionParticipantCamp) Presence() (rd.Plage, bool) {
    56  	// plus faible priorité
    57  	arrivee, depart := p.Camp.DateDebut, p.Camp.DateFin
    58  
    59  	options := p.Camp.OptionPrix
    60  	optionPart := p.OptionPrix
    61  	switch options.Active {
    62  	case rd.OptionsPrix.SEMAINE:
    63  		detailsOpt, semaine := options.Semaine, optionPart.Semaine
    64  		switch semaine {
    65  		case rd.SSe1:
    66  			arrivee, depart = safeChange(arrivee, detailsOpt.Plage1.From), safeChange(depart, detailsOpt.Plage1.To)
    67  		case rd.SSe2:
    68  			arrivee, depart = safeChange(arrivee, detailsOpt.Plage2.From), safeChange(depart, detailsOpt.Plage2.To)
    69  		}
    70  	case rd.OptionsPrix.JOUR:
    71  		// cas particulier: on renvoie la plage la plus proche
    72  		return optionPart.Jour.ClosestPlage(rd.Plage{From: p.Camp.DateDebut, To: p.Camp.DateFin}), true
    73  	}
    74  	return rd.Plage{From: arrivee, To: depart}, false
    75  }
    76  
    77  // NbJours renvoie le nombre de jours de présence du participant
    78  // en prenant en compte une éventulle option SEMAINE ou JOUR.
    79  func (p OptionParticipantCamp) NbJours() rd.Int {
    80  	plage, isJour := p.Presence()
    81  	if isJour {
    82  		// on ne peut pas utiliser la plage
    83  		return rd.Int(p.OptionPrix.Jour.NbJours(rd.Plage{From: p.Camp.DateDebut, To: p.Camp.DateFin}))
    84  	}
    85  	return rd.Int(plage.NbJours())
    86  }
    87  
    88  // IsFicheSanitaireUpToDate compare le moment d'inscription
    89  // avec la dernière modification sur la fiche sanitaire
    90  // Non : jamais remplie, zero : rempli mais non a jour, Oui OK
    91  func (p ParticipantPersonne) IsFicheSanitaireUpToDate() rd.OptionnalBool {
    92  	momentInsc := p.Participant.DateHeure
    93  	modifFiche := p.Personne.FicheSanitaire.LastModif
    94  	if modifFiche.Time().IsZero() {
    95  		return rd.OBNon
    96  	} else if modifFiche.Time().After(momentInsc.Time()) {
    97  		return rd.OBOui
    98  	}
    99  	return rd.OBPeutEtre
   100  }
   101  
   102  // Description renvoie un résumé de l'option, utilisable dans un tableau
   103  func (p OptionParticipantCamp) Description() rd.String {
   104  	optionPrixCamp := p.Camp.OptionPrix
   105  	optionActive := optionPrixCamp.Active
   106  	var desc string
   107  	switch optionActive {
   108  	case rd.OptionsPrix.SEMAINE:
   109  		semaine := p.OptionPrix.Semaine
   110  		desc = rd.SemaineLabels[semaine]
   111  	case rd.OptionsPrix.STATUT:
   112  		statutInfo := p.StatutPrix()
   113  		if statutInfo.Id != 0 {
   114  			desc = string(statutInfo.Statut)
   115  		}
   116  	case rd.OptionsPrix.QUOTIENT_FAMILIAL:
   117  		qf := p.OptionPrix.QuotientFamilial
   118  		if qf > 0 {
   119  			desc = "Quotient famil."
   120  		}
   121  	case rd.OptionsPrix.JOUR:
   122  		nbJours := p.NbJours()
   123  		prixJours := optionPrixCamp.Jour
   124  		if nbJours == 0 { // invalide -> camp entier
   125  			break
   126  		}
   127  		if int(nbJours) <= len(prixJours) {
   128  			s := ""
   129  			if nbJours > 1 {
   130  				s = "s"
   131  			}
   132  			desc = fmt.Sprintf("%d jour%s", nbJours, s)
   133  		}
   134  	}
   135  	return rd.String(desc)
   136  }