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  }