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

     1  // Ce package implémentes les fondements de la gestion des données
     2  // ACVE. Il est destiné à être utilisé sur le serveur et sur le client.
     3  // Il définit les types de donneés utilisés
     4  // et permet de changer d'une représentation à une autre (SQL/JSON/mémoire vive)
     5  package rawdata
     6  
     7  import (
     8  	"time"
     9  
    10  	"github.com/lib/pq"
    11  )
    12  
    13  // ----------------------------------- Personne ----------------------------------- //
    14  
    15  // Personne représente les attributs d'une personne
    16  type Personne struct {
    17  	Id int64 `json:"id"`
    18  
    19  	BasePersonne
    20  
    21  	VersionPapier    Bool           `json:"version_papier"`
    22  	PubHiver         Bool           `json:"pub_hiver"`
    23  	PubEte           Bool           `json:"pub_ete"`
    24  	EchoRocher       Bool           `json:"echo_rocher"`
    25  	RangMembreAsso   RangMembreAsso `json:"rang_membre_asso"`
    26  	QuotientFamilial Int            `json:"quotient_familial"`
    27  	Cotisation       Cotisation     `json:"cotisation"` // dernière année
    28  	Eonews           Bool           `json:"eonews"`
    29  	FicheSanitaire   FicheSanitaire `json:"fiche_sanitaire"`
    30  
    31  	// Si `true` indique un profil non vérifié. Les personnes temporaires
    32  	// peuvent être supprimées à tout moment (nécessitant une redirection des tables
    33  	// documents, participants,...)
    34  	IsTemporaire Bool `json:"is_temporaire"`
    35  }
    36  
    37  // ----------------------------------- Camp ----------------------------------- //
    38  
    39  // Camp représente un séjour proposé par l'ACVE
    40  // requis participantsimples
    41  // sql:ADD UNIQUE(id,inscription_simple)
    42  type Camp struct {
    43  	Id                int64       `json:"id"`
    44  	Lieu              String      `json:"lieu"`
    45  	Nom               String      `json:"nom"`
    46  	Prix              Euros       `json:"prix"`
    47  	NbPlaces          Int         `json:"nb_places"`
    48  	Password          String      `json:"password"`
    49  	Ouvert            Bool        `json:"ouvert"`
    50  	NbPlacesReservees Int         `json:"nb_places_reservees"`
    51  	NumeroJS          String      `json:"numero_js"`
    52  	NeedEquilibreGf   Bool        `json:"need_equilibre_gf"`
    53  	AgeMin            Int         `json:"age_min"`
    54  	AgeMax            Int         `json:"age_max"`
    55  	Options           OptionsCamp `json:"options"`
    56  	DateDebut         Date        `json:"date_debut"`
    57  	DateFin           Date        `json:"date_fin"`
    58  
    59  	ListeVetements ListeVetements `json:"liste_vetements"`
    60  	SchemaPaiement SchemaPaiement `json:"schema_paiement"`
    61  	JoomeoAlbumId  String         `json:"joomeo_album_id"`
    62  	Envois         Envois         `json:"envois"`
    63  	LienCompta     String         `json:"lien_compta"`
    64  	OptionPrix     OptionPrixCamp `json:"option_prix"`
    65  
    66  	// Si oui, la procédure d'inscription est simplifiée.
    67  	InscriptionSimple Bool `json:"inscription_simple"`
    68  
    69  	Infos String `json:"infos"` // info additionnelle à afficher sur le formulaire
    70  }
    71  
    72  // LettreDirecteur conserve le html utilisé pour générer la lettre.
    73  // En revanche, c'est bien le document stocké dans la base de données
    74  // qui est utilisé ensuie.
    75  // Le contenu html de la lettre peut contenir des images
    76  // et alourdir significativement la table Camps.
    77  // sql:ADD UNIQUE(id_camp)
    78  type Lettredirecteur struct {
    79  	IdCamp             int64  `json:"id_camp" sql_on_delete:"CASCADE"`
    80  	Html               string `json:"html"`
    81  	UseCoordCentre     bool   `json:"use_coord_centre"`
    82  	ShowAdressePostale bool   `json:"show_adresse_postale"`
    83  	ColorCoord         string `json:"color_coord"`
    84  }
    85  
    86  // Images contenues dans les lettres aux parents
    87  // sql: ADD UNIQUE(id_camp, lien)
    88  type Imageuploaded struct {
    89  	IdCamp   int64  `json:"id_camp" sql_on_delete:"CASCADE"`
    90  	Filename string `json:"filename"`
    91  	Lien     string `json:"lien"`
    92  	Content  []byte `json:"content"`
    93  }
    94  
    95  // Groupe représente un groupe de participants
    96  // Un séjour peut définir (ou non) une liste de groupes
    97  // sql:ADD UNIQUE(id_camp, nom)
    98  // sql:ADD UNIQUE(id, id_camp)
    99  // assure qu'un groupe est lié à un camp complet
   100  // sql:ALTER COLUMN isSimple SET DEFAULT false
   101  // sql:ADD CHECK(isSimple = false)
   102  // sql:ADD FOREIGN KEY (id_camp, isSimple) REFERENCES camps(id,inscription_simple)
   103  type Groupe struct {
   104  	Id     int64 `json:"id"`
   105  	IdCamp int64 `json:"id_camp" sql_on_delete:"CASCADE"`
   106  
   107  	// un nom vide indique un groupe par défaut
   108  	Nom String `json:"nom"`
   109  	// indication: ignorée forcément pour un groupe par défaut
   110  	Plage Plage `json:"plage"`
   111  	// Hex color, optionnelle
   112  	Couleur string `json:"couleur"`
   113  
   114  	isSimple bool
   115  }
   116  
   117  // Sondage enregistre les retours sur un séjour
   118  // sql:ADD UNIQUE(id_camp, id_facture)
   119  type Sondage struct {
   120  	Id        int64     `json:"id"`
   121  	IdCamp    int64     `json:"id_camp" sql_on_delete:"CASCADE"`
   122  	IdFacture int64     `json:"id_facture" sql_on_delete:"CASCADE"`
   123  	Modified  time.Time `json:"modified"`
   124  
   125  	RepSondage
   126  }
   127  
   128  // ------------------------------ Inscriptions ------------------------------
   129  
   130  // Inscription enregistre l'inscription faite via le formulaire publique.
   131  // L'inscription publique est transformée en facture dès réception,
   132  // cette table ne sert donc qu'à garder une trace en cas de problème.
   133  // Entre autre, l'intégrité des camps n'est pas assurée
   134  type Inscription struct {
   135  	Id          int64          `json:"id"`
   136  	Info        String         `json:"info"`
   137  	DateHeure   Time           `json:"date_heure"`
   138  	CopiesMails pq.StringArray `json:"copies_mails"`
   139  
   140  	Responsable  ResponsableLegal        `json:"responsable"`
   141  	Participants ParticipantInscriptions `json:"participants"`
   142  
   143  	PartageAdressesOK bool `json:"partage_adresses_ok"`
   144  }
   145  
   146  // -------------------------- Participants --------------------------
   147  
   148  // Participant représente un inscrit sur un séjour complet (éventuellement sur liste d'attente)
   149  // sql:ADD UNIQUE(id_personne, id_camp)
   150  // nécessaire pour être référencé
   151  // sql:ADD UNIQUE(id, id_camp)
   152  // assure qu'un participant est lié à un camp complet
   153  // sql:ALTER COLUMN isSimple SET DEFAULT false
   154  // sql:ADD CHECK(isSimple = false)
   155  // sql:ADD FOREIGN KEY (id_camp, isSimple) REFERENCES camps(id,inscription_simple)
   156  type Participant struct {
   157  	Id         int64       `json:"id"`
   158  	IdCamp     int64       `json:"id_camp"`
   159  	IdPersonne int64       `json:"id_personne" sql_on_delete:"CASCADE"`
   160  	IdFacture  OptionnalId `json:"id_facture" sql_on_delete:"SET NULL"`
   161  
   162  	ListeAttente ListeAttente          `json:"liste_attente"`
   163  	Remises      Remises               `json:"remises"`
   164  	OptionPrix   OptionPrixParticipant `json:"option_prix"`
   165  	Options      OptionsParticipant    `json:"options"`
   166  
   167  	// Moment d'inscription
   168  	DateHeure Time `json:"date_heure"`
   169  
   170  	isSimple bool
   171  }
   172  
   173  // GroupeParticipant défini le contenu des groupes
   174  // sql:ADD UNIQUE (id_participant)
   175  // sql:ADD UNIQUE (id_participant, id_groupe)
   176  // sql:ADD FOREIGN KEY (id_participant, id_camp) REFERENCES participants(id,id_camp)
   177  // sql:ADD FOREIGN KEY (id_groupe, id_camp) REFERENCES groupes(id,id_camp)
   178  type GroupeParticipant struct {
   179  	IdParticipant int64 `json:"id_participant" sql_on_delete:"CASCADE"`
   180  	IdGroupe      int64 `json:"id_groupe" sql_on_delete:"CASCADE"`
   181  	// redondance pour assurer l'intégrité
   182  	IdCamp int64 `json:"id_camp"`
   183  	// indique si l'attribuation a été faite
   184  	// en modifiant directement la fiche du participant ou
   185  	// en fonction de l'âge
   186  	Manuel bool `json:"manuel"`
   187  }
   188  
   189  // Equipier représente un participant dans l'équipe d'un séjour
   190  // sql:ADD UNIQUE(id_personne, id_camp)
   191  // requise par la contrainte ParticipantEquipier
   192  // sql:ADD UNIQUE(id, id_camp)
   193  type Equipier struct {
   194  	Id         int64 `json:"id"`
   195  	IdCamp     int64 `json:"id_camp"`
   196  	IdPersonne int64 `json:"id_personne" sql_on_delete:"CASCADE"`
   197  
   198  	Roles              Roles              `json:"roles"`
   199  	Diplome            Diplome            `json:"diplome"`
   200  	Appro              Approfondissement  `json:"appro"`
   201  	Presence           OptionnalPlage     `json:"presence"`
   202  	InvitationEquipier InvitationEquipier `json:"invitation_equipier"`
   203  
   204  	// validation de la charte ACVE
   205  	Charte OptionnalBool `json:"charte"`
   206  }
   207  
   208  // GroupeEquipiers définit les animateurs d'un groupe
   209  // sql:ADD UNIQUE(id_groupe, id_equipier)
   210  // sql:ADD FOREIGN KEY (id_equipier, id_camp) REFERENCES equipiers(id,id_camp)
   211  // sql:ADD FOREIGN KEY (id_groupe, id_camp) REFERENCES groupes(id,id_camp)
   212  type GroupeEquipier struct {
   213  	IdGroupe   int64 `json:"id_groupe" sql_on_delete:"CASCADE"`
   214  	IdEquipier int64 `json:"id_equipier" sql_on_delete:"CASCADE"`
   215  	// redondance pour assurer l'intégrité
   216  	IdCamp int64 `json:"id_camp" sql_on_delete:"CASCADE"`
   217  }
   218  
   219  // ParticipantEquipier associe un animateur de référence à un inscrit
   220  // sql:ADD UNIQUE (id_participant)
   221  // sql:ADD FOREIGN KEY (id_participant, id_groupe) REFERENCES groupe_participants(id_participant, id_groupe)
   222  // sql:ADD FOREIGN KEY (id_equipier, id_groupe) REFERENCES groupe_equipiers(id_equipier, id_groupe) ON DELETE CASCADE
   223  type ParticipantEquipier struct {
   224  	IdParticipant int64 `json:"id_participant" sql_on_delete:"CASCADE"`
   225  	IdEquipier    int64 `json:"id_equipier" sql_on_delete:"CASCADE"`
   226  	// redondance pour assurer l'intégrité
   227  	IdGroupe int64 `json:"id_groupe" sql_on_delete:"CASCADE"`
   228  }
   229  
   230  // Participantsimple représente un inscrit sur un séjour simplifié,
   231  // sans dossier ni groupe associé.
   232  // sql:ADD UNIQUE(id_personne, id_camp)
   233  // assure qu'un participant simple appartient à un camp simple
   234  // sql:ALTER COLUMN isSimple SET DEFAULT TRUE
   235  // sql:ADD CHECK(isSimple = TRUE)
   236  // sql:ADD FOREIGN KEY (id_camp, isSimple) REFERENCES camps(id,inscription_simple)
   237  type Participantsimple struct {
   238  	Id         int64 `json:"id"`
   239  	IdPersonne int64 `json:"id_personne" sql_on_delete:"CASCADE"`
   240  	IdCamp     int64 `json:"id_camp"` // devrait être simple
   241  
   242  	// Moment d'inscription
   243  	DateHeure Time   `json:"date_heure"`
   244  	Info      String `json:"info"`
   245  
   246  	isSimple bool
   247  }
   248  
   249  type Structureaide struct {
   250  	Id              int64  `json:"id"`
   251  	Nom             String `json:"nom"`
   252  	Immatriculation String `json:"immatriculation"`
   253  	Adresse         String `json:"adresse"`
   254  	CodePostal      String `json:"code_postal"`
   255  	Ville           String `json:"ville"`
   256  	Telephone       String `json:"telephone"`
   257  	Info            String `json:"info"`
   258  }
   259  
   260  type Aide struct {
   261  	Id              int64 `json:"id"`
   262  	IdStructureaide int64 `json:"id_structureaide"`
   263  	IdParticipant   int64 `json:"id_participant" sql_on_delete:"CASCADE"`
   264  	Valeur          Euros `json:"valeur"`
   265  	Valide          Bool  `json:"valide"`
   266  	ParJour         Bool  `json:"par_jour"`
   267  	NbJoursMax      Int   `json:"nb_jours_max"`
   268  }
   269  
   270  // Organisme désigne un groupe de personne (typiquement une église)
   271  // Un organisme a soit des coordonnées propre, soit une personne de contact
   272  // En plus, un contact pour les dons peut être ajouté.
   273  // sql:ADD CHECK(contact_propre <> (id_contact IS NOT NULL))
   274  type Organisme struct {
   275  	Id  int64  `json:"id"`
   276  	Nom String `json:"nom"`
   277  
   278  	ContactPropre Bool        `json:"contact_propre"`
   279  	Contact       Coordonnees `json:"contact"`
   280  	IdContact     OptionnalId `json:"id_contact" sql_foreign_key:"personne"`
   281  
   282  	IdContactDon OptionnalId `json:"id_contact_don" sql_foreign_key:"personne"`
   283  	Exemplaires  Exemplaires `json:"exemplaires"` // pour les communications
   284  }
   285  
   286  type Don struct {
   287  	Id            int64       `json:"id"`
   288  	Valeur        Euros       `json:"valeur"`
   289  	ModePaiement  ModePaiment `json:"mode_paiement"`
   290  	DateReception Date        `json:"date_reception"`
   291  	RecuEmis      Date        `json:"recu_emis"`
   292  	Infos         InfoDon     `json:"infos"`
   293  	Remercie      Bool        `json:"remercie"`    // `true` si le remerciement a été envoyé
   294  	Details       String      `json:"details"`     // détails additionels
   295  	Affectation   String      `json:"affectation"` // indicatif
   296  }
   297  
   298  // DonDonateur est une table de lien indiquant l'origine d'un don,
   299  // groupe ou personne
   300  // sql:ADD CHECK(id_personne <> null OR id_organisme <> null)
   301  // sql:ADD CHECK(id_personne = null OR id_organisme = null)
   302  // sql:ADD UNIQUE(id_don)
   303  type DonDonateur struct {
   304  	IdDon       int64       `json:"id_don" sql_on_delete:"CASCADE"`
   305  	IdPersonne  OptionnalId `json:"id_personne"`
   306  	IdOrganisme OptionnalId `json:"id_organisme"`
   307  }
   308  
   309  // ---------------------------- Documents et contraintes ----------------------------
   310  
   311  // Contrainte encode la catégorie d'un document à fournir
   312  // L'attribut 'builtin' permet d'identifier des contraintes universelles
   313  //
   314  // sql:ADD UNIQUE(nom, builtin, id_personne)
   315  // sql:ADD CHECK(builtin <> '' OR id_personne IS NOT NULL)
   316  type Contrainte struct {
   317  	Id         int64       `json:"id"`
   318  	IdPersonne OptionnalId `json:"id_personne" sql_on_delete:"CASCADE"` // proprietaire de la contrainte
   319  	IdDocument OptionnalId `json:"id_document"`                         // document à remplir
   320  
   321  	Builtin     BuiltinContrainte `json:"builtin"`
   322  	Nom         String            `json:"nom"`
   323  	Description String            `json:"description"`
   324  	// nombre max de documents qui peuvent satisfaire la contrainte
   325  	MaxDocs int `json:"max_docs"`
   326  	// si > 0 indique un document temporaire :
   327  	// les documents liés seront supprimés JoursValide jours
   328  	// après leur dernière modification
   329  	JoursValide int `json:"jours_valide"`
   330  }
   331  
   332  // sql:ADD UNIQUE(id_equipier, id_contrainte)
   333  type EquipierContrainte struct {
   334  	IdEquipier   int64 `json:"id_equipier" sql_on_delete:"CASCADE"`
   335  	IdContrainte int64 `json:"id_contrainte"`
   336  	Optionnel    bool  `json:"optionnel"`
   337  }
   338  
   339  // CampContrainte représente une contrainte demandée
   340  // à tous les participants
   341  // sql:ADD UNIQUE(id_camp, id_contrainte)
   342  type CampContrainte struct {
   343  	IdCamp       int64 `json:"id_camp" sql_on_delete:"CASCADE"`
   344  	IdContrainte int64 `json:"id_contrainte"`
   345  }
   346  
   347  // GroupeContrainte représente une contrainte
   348  // attribuée à un groupe spécifique (de façon cumulative
   349  // avec les contraintes camps)
   350  // sql:ADD UNIQUE(id_groupe, id_contrainte)
   351  type GroupeContrainte struct {
   352  	IdGroupe     int64 `json:"id_groupe" sql_on_delete:"CASCADE"`
   353  	IdContrainte int64 `json:"id_contrainte"`
   354  }
   355  
   356  // Document représente les méta données d'un document stocké sur le serveur
   357  // Son contenu et son utilisation sont définis par les objets `TargetDocument` et `ContenuDocument`
   358  type Document struct {
   359  	Id int64 `json:"id"`
   360  
   361  	// En bytes
   362  	Taille         Taille `json:"taille"`
   363  	NomClient      String `json:"nom_client"`
   364  	Description    String `json:"description"`
   365  	DateHeureModif Time   `json:"date_heure_modif"`
   366  }
   367  
   368  // ContenuDocument stocke le contenu effectif du document, compressé
   369  // ainsi qu'une miniature
   370  // sql:ADD UNIQUE(id_document)
   371  type ContenuDocument struct {
   372  	IdDocument int64  `json:"id_document" sql_on_delete:"CASCADE"`
   373  	Contenu    []byte `json:"contenu"`
   374  	Miniature  []byte `json:"miniature"`
   375  }
   376  
   377  // table de lien pour les lettres des séjours et les documents additionnels
   378  // sql:	ADD UNIQUE(id_document)
   379  type DocumentCamp struct {
   380  	IdDocument int64 `json:"id_document" sql_on_delete:"CASCADE"`
   381  	IdCamp     int64 `json:"id_camp"`
   382  	IsLettre   bool  `json:"is_lettre"` // sinon, document additionnel
   383  }
   384  
   385  // table de lien pour les documents liés aux personnes
   386  // un document peut remplir une contrainte personnalisée
   387  // sql:ADD UNIQUE(id_document)
   388  type DocumentPersonne struct {
   389  	IdDocument   int64 `json:"id_document" sql_on_delete:"CASCADE"`
   390  	IdPersonne   int64 `json:"id_personne"`
   391  	IdContrainte int64 `json:"id_contrainte"`
   392  }
   393  
   394  // table de lien pour les justificatifs des aides
   395  // sql:ADD UNIQUE(id_document)
   396  type DocumentAide struct {
   397  	IdDocument int64 `json:"id_document" sql_on_delete:"CASCADE"`
   398  	IdAide     int64 `json:"id_aide"`
   399  }
   400  
   401  // --------------------------------- ---------------------------------
   402  type Paiement struct {
   403  	Id        int64 `json:"id"`
   404  	IdFacture int64 `json:"id_facture"`
   405  
   406  	IsAcompte       Bool        `json:"is_acompte"`
   407  	IsRemboursement Bool        `json:"is_remboursement"`
   408  	InBordereau     Time        `json:"in_bordereau"`
   409  	LabelPayeur     String      `json:"label_payeur"`
   410  	NomBanque       String      `json:"nom_banque"`
   411  	ModePaiement    ModePaiment `json:"mode_paiement"`
   412  	Numero          String      `json:"numero"`
   413  	Valeur          Euros       `json:"valeur"`
   414  	IsInvalide      Bool        `json:"is_invalide"`
   415  	DateReglement   Time        `json:"date_reglement"`
   416  	Details         String      `json:"details"`
   417  }
   418  
   419  type Facture struct {
   420  	Id                      int64                   `json:"id"`
   421  	IdPersonne              int64                   `json:"id_personne"`
   422  	DestinatairesOptionnels DestinatairesOptionnels `json:"destinataires_optionnels"`
   423  	Key                     String                  `json:"key"`
   424  	CopiesMails             pq.StringArray          `json:"copies_mails"` // liste d'adresse en copies des mails envoyés
   425  
   426  	LastConnection time.Time `json:"last_connection"` // connection sur l'espace de suivi
   427  
   428  	IsConfirmed bool `json:"is_confirmed"` // mail confirmé par les parents
   429  	IsValidated bool `json:"is_validated"` // validée par le centre
   430  
   431  	// Autorisation de partage des adresses
   432  	PartageAdressesOK bool `json:"partage_adresses_ok"`
   433  }
   434  
   435  // Message encode un échange entre le centre d'inscription
   436  // et le responsable d'un dossier
   437  // sql:ADD UNIQUE(id, kind)
   438  // Les définitions suivantes sont temporaires et permettent de
   439  // solidifer la migration
   440  // noTableSql:CREATE FUNCTION m_responsable() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MResponsable';
   441  // noTableSql:CREATE FUNCTION m_centre() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MCentre';
   442  // noTableSql:CREATE FUNCTION m_accuse_reception() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MAccuseReception';
   443  // noTableSql:CREATE FUNCTION m_facture() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MFacture';
   444  // noTableSql:CREATE FUNCTION m_documents() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MDocuments';
   445  // noTableSql:CREATE FUNCTION m_facture_acquittee() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MFactureAcquittee';
   446  // noTableSql:CREATE FUNCTION m_attestation_presence() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MAttestationPresence';
   447  // noTableSql:CREATE FUNCTION m_sondage() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MSondage';
   448  // noTableSql:CREATE FUNCTION m_inscription() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MInscription';
   449  // noTableSql:CREATE FUNCTION m_place_liberee() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #MessageKind.MPlaceLiberee';
   450  type Message struct {
   451  	Id        int64       `json:"id"`
   452  	IdFacture int64       `json:"id_facture" sql_on_delete:"CASCADE"`
   453  	Kind      MessageKind `json:"kind"`
   454  	Created   Time        `json:"created"`
   455  	Modified  Time        `json:"modified"`
   456  	Vu        bool        `json:"vu"` // indique si le message a été vu (dépend du contexte)
   457  }
   458  
   459  // Définit les tables complétant un message (à garder synchronisé)
   460  var ComplementMessagesTables = [5]string{
   461  	"message_documents",
   462  	"message_sondages",
   463  	"message_placeliberes",
   464  	"message_attestations",
   465  	"message_messages",
   466  }
   467  
   468  // MessageDocument complete un message 'documents'
   469  // en donnant le camp concerné.
   470  // sql:ADD UNIQUE(id_message)
   471  // contraintes d'intégrité :
   472  // sql:ADD CHECK(guardKind = #MessageKind.MDocuments)
   473  // sql:ALTER COLUMN guardKind SET DEFAULT #MessageKind.MDocuments
   474  // sql:ADD FOREIGN KEY (id_message, guardKind) REFERENCES messages(id,kind)
   475  type MessageDocument struct {
   476  	IdMessage int64 `json:"id_message" sql_on_delete:"CASCADE"`
   477  	IdCamp    int64 `json:"id_camp"`
   478  
   479  	guardKind MessageKind
   480  }
   481  
   482  // MessageSondage complete un message 'sondage'
   483  // en donnant le camp concerné.
   484  // sql:ADD UNIQUE(id_message)
   485  // contraintes d'intégrité :
   486  // sql:ADD CHECK(guardKind = #MessageKind.MSondage)
   487  // sql:ALTER COLUMN guardKind SET DEFAULT #MessageKind.MSondage
   488  // sql:ADD FOREIGN KEY (id_message, guardKind) REFERENCES messages(id,kind)
   489  // sql:ALTER COLUMN isSimple SET DEFAULT FALSE
   490  // sql:ADD CHECK(isSimple = FALSE)
   491  // sql:ADD FOREIGN KEY (id_camp, isSimple) REFERENCES camps(id,inscription_simple)
   492  type MessageSondage struct {
   493  	IdMessage int64 `json:"id_message" sql_on_delete:"CASCADE"`
   494  	IdCamp    int64 `json:"id_camp"`
   495  
   496  	guardKind MessageKind
   497  	isSimple  bool
   498  }
   499  
   500  // MessagePlacelibere complète une notification de place libérée
   501  // sql:ADD UNIQUE(id_message)
   502  // contraintes d'intégrité :
   503  // sql:ADD CHECK(guardKind = #MessageKind.MPlaceLiberee)
   504  // sql:ALTER COLUMN guardKind SET DEFAULT #MessageKind.MPlaceLiberee
   505  // sql:ADD FOREIGN KEY (id_message, guardKind) REFERENCES messages(id,kind)
   506  type MessagePlacelibere struct {
   507  	IdMessage     int64 `json:"id_message" sql_on_delete:"CASCADE"`
   508  	IdParticipant int64 `json:"id_participant"`
   509  
   510  	guardKind MessageKind
   511  }
   512  
   513  // MessageAttestation complète l'accès
   514  // à une facture acquittée/attestation de présence
   515  // sql:ADD UNIQUE(id_message)
   516  // contraintes d'intégrité :
   517  // sql:ADD CHECK(guard_kind = #MessageKind.MFactureAcquittee OR guard_kind = #MessageKind.MAttestationPresence)
   518  // sql:ADD FOREIGN KEY (id_message, guard_kind) REFERENCES messages(id,kind)
   519  // pour la migration
   520  // noTableSql:CREATE FUNCTION d_mail() RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT #Distribution.DMail';
   521  type MessageAttestation struct {
   522  	IdMessage    int64        `json:"id_message" sql_on_delete:"CASCADE"`
   523  	Distribution Distribution `json:"distribution"`
   524  
   525  	GuardKind MessageKind `json:"guard_kind"`
   526  }
   527  
   528  // MessageMessage complète l'accès à un message libre
   529  // sql:ADD UNIQUE(id_message)
   530  // contraintes d'intégrité :
   531  // sql:ADD CHECK(guard_kind = #MessageKind.MResponsable OR guard_kind = #MessageKind.MCentre)
   532  // sql:ADD FOREIGN KEY (id_message, guard_kind) REFERENCES messages(id,kind)
   533  type MessageMessage struct {
   534  	IdMessage int64  `json:"id_message" sql_on_delete:"CASCADE"`
   535  	Contenu   String `json:"contenu"`
   536  
   537  	GuardKind MessageKind `json:"guard_kind"`
   538  }
   539  
   540  // ---------------------------- Users ----------------------------
   541  
   542  // User représente un utilisateur du client
   543  type User struct {
   544  	Id      int64   `json:"id"`
   545  	Label   String  `json:"label"`
   546  	Mdp     String  `json:"mdp"`
   547  	IsAdmin Bool    `json:"is_admin"`
   548  	Modules Modules `json:"modules"`
   549  }