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 }