github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/core/rawdata/composites/camps.go (about) 1 package composites 2 3 import ( 4 rd "github.com/benoitkugler/goACVE/server/core/rawdata" 5 ) 6 7 // CampParticipants ajoute les participants (inscrits et liste d'attente) 8 // à un séjour (complet) 9 type CampParticipants struct { 10 rd.Camp 11 Participants []rd.Participant 12 } 13 14 // NewCampParticipants sélectionne les participant dans un dictionnaire possiblement 15 // plus vaste 16 func NewCampParticipants(camp rd.Camp, participants rd.Participants) CampParticipants { 17 var out []rd.Participant 18 for _, participant := range participants { 19 if participant.IdCamp == camp.Id { 20 out = append(out, participant) 21 } 22 } 23 return CampParticipants{Camp: camp, Participants: out} 24 } 25 26 // RestePlace renvoie `true` si l'ajout de zéro ou un inscrit 27 // ne dépasse pas le nombre de places autorisées (nombre de places - places réservées) 28 func (c CampParticipants) RestePlace(isCurrentInscrit bool) rd.StatutAttente { 29 places := c.Camp.NbPlaces - c.Camp.NbPlacesReservees 30 var actuelles rd.Int 31 for _, part := range c.Participants { 32 if part.ListeAttente.IsInscrit() { 33 actuelles += 1 34 } 35 } 36 if isCurrentInscrit { // on décompte le participant actuel 37 actuelles-- 38 } 39 if places > actuelles { 40 return rd.Inscrit 41 } 42 return rd.Attente 43 } 44 45 // sexeInscrits renvoie le nombre de garçons/filles inscrits 46 // `personnes` doit contenir les personnes liées aux participants 47 func (c CampParticipants) sexeInscrits(personnes rd.Personnes) (nbGarcons, nbFilles int) { 48 for _, part := range c.Participants { 49 if part.ListeAttente.Statut != rd.Inscrit { 50 continue 51 } 52 switch personnes[part.IdPersonne].Sexe { 53 case rd.SHomme: 54 nbGarcons += 1 55 case rd.SFemme: 56 nbFilles += 1 57 } 58 } 59 return nbGarcons, nbFilles 60 } 61 62 // KeepEquilibreGF renvoie `true` si l'ajout de zéro ou un participant du sexe donné 63 // ne dépasse pas le quota G/F ou si le camp ne demande pas d'équilibre. 64 func (c CampParticipants) KeepEquilibreGF(s rd.Sexe, isCurrentInscrit bool, personnes rd.Personnes) rd.StatutAttente { 65 if !c.Camp.NeedEquilibreGf { 66 return rd.Inscrit 67 } 68 nbGarcons, nbFilles := c.sexeInscrits(personnes) 69 var ok bool 70 switch s { 71 case rd.SHomme: 72 if isCurrentInscrit { // on décompte le participant déjà inscrit 73 nbGarcons-- 74 } 75 nbGarcons++ 76 ok = nbGarcons <= int(c.Camp.NbPlaces*2/3) 77 case rd.SFemme: 78 if isCurrentInscrit { // on décompte le participant déjà inscrit 79 nbFilles-- 80 } 81 nbFilles++ 82 ok = nbFilles <= int(c.Camp.NbPlaces*2/3) 83 default: // en l'absence d'info, on considère que l'équilibre n'est pas dérangé 84 ok = true 85 } 86 if ok { 87 return rd.Inscrit 88 } 89 return rd.Attente 90 } 91 92 // HintsAttente vérifie les conditions de liste d'attente 93 // `personnes` doit contenir les personnes déjà inscrites 94 func (c CampParticipants) HintsAttente(pers rd.BasePersonne, isCurrentInscrit bool, personnes rd.Personnes) rd.HintsAttente { 95 statusMin, statusMax := c.Camp.HasAgeValide(pers) 96 return rd.HintsAttente{ 97 AgeMin: statusMin, 98 AgeMax: statusMax, 99 Place: c.RestePlace(isCurrentInscrit), 100 EquilibreGF: c.KeepEquilibreGF(pers.Sexe, isCurrentInscrit, personnes), 101 } 102 } 103 104 // IsParticipantAlreadyHere vérifie si le potentiel participant n'est pas déjà présent 105 // dans le camp. 106 func (c CampParticipants) IsParticipantAlreadyHere(idPersonne int64) bool { 107 for _, part := range c.Participants { 108 if part.IdPersonne == idPersonne { 109 return true 110 } 111 } 112 return false 113 } 114 115 // CampParticipants ajoute les groupes à un séjour (complet) 116 type CampGroupes struct { 117 rd.Camp 118 Groupes []rd.Groupe 119 } 120 121 // NewCampGroupes sélectionne les groupes du camp, parmi un dictionnaire 122 // possiblement plus important 123 func NewCampGroupes(camp rd.Camp, groupes rd.Groupes) CampGroupes { 124 var out []rd.Groupe 125 for _, g := range groupes { 126 if g.IdCamp == camp.Id { 127 out = append(out, g) 128 } 129 } 130 return CampGroupes{Camp: camp, Groupes: out} 131 } 132 133 // TrouveGroupe cherche parmis les groupes possibles celui qui pourrait convenir. 134 // Normalement, les groupes respectent un invariant de continuité sur les plages, 135 // imposé par le frontend. 136 // Si plusieurs pouvait convenir, un seul est renvoyé, de façon arbitraire. 137 func (c CampGroupes) TrouveGroupe(dateNaissance rd.Date) (rd.Groupe, bool) { 138 for _, g := range c.Groupes { 139 if g.Plage.Contains(dateNaissance.Time()) { 140 return g, true 141 } 142 } 143 // on a trouvé aucun groupe 144 return rd.Groupe{}, false 145 }