github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/frontend/directeurs/src/logic/controller.ts (about)

     1  import Vue from "vue";
     2  import Axios, { AxiosResponse } from "axios";
     3  import Cookie from "js-cookie";
     4  
     5  import { Directeurs } from "./api";
     6  import { Notifications } from "./notifications";
     7  import {
     8    AddBonusDocOut,
     9    AddContactJoomeoIn,
    10    AddContactJoomeoOut,
    11    AddDocumentIn,
    12    AddDocumentOut,
    13    ChercheSimilaireOut,
    14    Contrainte,
    15    CreateEquipierIn,
    16    DeleteContactOut,
    17    DeleteContrainteOut,
    18    DetailsDetailsOutput,
    19    DetailsEnvoisOut,
    20    DetailsWritable,
    21    DocumentsEquipeOut,
    22    DownloadFicheSanitaireIn,
    23    Envois,
    24    EquipierDirecteur,
    25    Groupe,
    26    GroupeContraintes,
    27    InviteFormulaireIn,
    28    Lettredirecteur,
    29    LettreDirecteurOut,
    30    LieDocumentOut,
    31    ListeVetements,
    32    ListeVetementsOut,
    33    LoadContraintesOut,
    34    LoadEquipiersOut,
    35    LoadGroupesOut,
    36    LoadInscritsOut,
    37    LoadJoomeoOut,
    38    LogginIn,
    39    LogginOut,
    40    OptionnalId,
    41    PatternsSimilarite,
    42    Pieces,
    43    PublicDocument,
    44    SetContactUploaderIn,
    45    SetContactUploaderOut,
    46    UpdateContrainteOut,
    47    UpdateGroupeOut,
    48    UpdateInscritIn,
    49    UpdatePlageIn,
    50    UpdatePlageOut,
    51    Groupes,
    52    Inscrit,
    53    ContrainteComplete,
    54    PreviewDocumentsParticipantsOut,
    55    CampMeta,
    56    LoadSondagesOut,
    57    DemandeContraintesIn,
    58    CampContraintes,
    59    ResumeMessage,
    60    Responsable,
    61    MessageKind,
    62    LoadGroupeAnimateursOut,
    63    AddGroupeAnimateursIn,
    64    DeleteGroupeAnimateurIn,
    65    UpdateInscritsAnimateurIn,
    66    UpdateInsritsAnimateurOut,
    67    Bus,
    68    UpdateContrainteEquipierIn
    69  } from "./types";
    70  import { NullDate, Formatter } from "./formatter";
    71  
    72  export const devMode = process.env.NODE_ENV != "production";
    73  const host = devMode ? "http://localhost:1323" : window.location.origin;
    74  export const BASE_URL = host + "/directeurs/api/";
    75  const UrlDocuments = host + "/document";
    76  
    77  const IsSimple = "simple";
    78  
    79  function parseContentDisposition(header: string) {
    80    const startIndex = header.indexOf("filename=") + 9; // Adjust '+ 9' if filename is not the right one.
    81    const endIndex = header.length; //Check if '- 1' is necessary
    82    return header.substring(startIndex, endIndex);
    83  }
    84  
    85  function saveBlobAsFile(binaryData: Blob, filename: string) {
    86    const url = window.URL.createObjectURL(new Blob([binaryData]));
    87    const link = document.createElement("a");
    88    link.href = url;
    89    link.setAttribute("download", filename);
    90    document.body.appendChild(link);
    91    link.click();
    92    window.URL.revokeObjectURL(url);
    93  }
    94  
    95  /** returns the filename */
    96  function downloadFile(r: AxiosResponse<Blob>) {
    97    const filename =
    98      parseContentDisposition(r.headers["content-disposition"]) || "document";
    99    saveBlobAsFile(r.data, filename);
   100    return filename;
   101  }
   102  
   103  /** Regroupe les messages par dossier */
   104  export interface DossierMessages {
   105    responsable: Responsable;
   106    messages: ResumeMessage[];
   107    participants: Inscrit[];
   108  }
   109  
   110  /** Regroupes les requetes à effectuer au serveur (API portail des directeurs) */
   111  export class Controller {
   112    logs = { id_camp: "", token: "" };
   113    camp = { nom_camp: "", lien_compta: "", is_simple: false };
   114  
   115    notifications: Notifications;
   116  
   117    inscrits: Inscrit[] = [];
   118    groupes: NonNullable<Groupes> = {};
   119    campContraintes: NonNullable<CampContraintes> = [];
   120    groupeContraintes: NonNullable<GroupeContraintes> = [];
   121    contraintes: { [key: number]: ContrainteComplete } = {};
   122  
   123    constructor() {
   124      this.notifications = new Notifications();
   125    }
   126  
   127    private getAuth() {
   128      return {
   129        username: this.logs.id_camp,
   130        password: this.logs.token
   131      };
   132    }
   133  
   134    /** Url sécurisé d'upload d'image */
   135    getUrlUploadImage() {
   136      return (
   137        BASE_URL +
   138        Directeurs.UploadImageLettre(this.logs.id_camp, this.logs.token)
   139      );
   140    }
   141  
   142    async getIdentification() {
   143      try {
   144        this.notifications.progress = true;
   145        const r: AxiosResponse<CampMeta[]> = await Axios.get(
   146          BASE_URL + Directeurs.DataLoggin
   147        );
   148        this.notifications.progress = false;
   149        return r.data;
   150      } catch (error) {
   151        this.notifications.onAxiosError(error);
   152      }
   153    }
   154  
   155    async postIdentification(params: LogginIn) {
   156      try {
   157        this.notifications.progress = true;
   158        const r: AxiosResponse<LogginOut> = await Axios.post(
   159          BASE_URL + Directeurs.Loggin,
   160          params
   161        );
   162        this.logs.token = r.data.token;
   163        this.notifications.progress = false;
   164        return r.data;
   165      } catch (error) {
   166        this.notifications.onAxiosError(error);
   167      }
   168      this.notifications.progress = false;
   169    }
   170  
   171    /** Lit les cookies et setup les informations */
   172    tryLogginCookie() {
   173      const id_camp = Cookie.get("id_camp");
   174      const token = Cookie.get("token");
   175      const lien_compta = Cookie.get("lien_compta") || "";
   176      const nom_camp = Cookie.get("nom_camp") || "";
   177      const is_simple = Cookie.get("is_simple") == IsSimple;
   178      if (id_camp && token) {
   179        this.setupLogs(id_camp, {
   180          camp: { label: nom_camp, is_simple },
   181          token,
   182          lien_compta
   183        });
   184        return true;
   185      }
   186      return false;
   187    }
   188  
   189    private setupLogs(idCamp: string, data: LogginData) {
   190      this.logs.id_camp = idCamp;
   191      this.logs.token = data.token;
   192      this.camp.nom_camp = data.camp.label;
   193      this.camp.lien_compta = data.lien_compta;
   194      this.camp.is_simple = data.camp.is_simple;
   195    }
   196  
   197    onLogginSuccess(idCamp: string, data: LogginData) {
   198      this.setupLogs(idCamp, data);
   199  
   200      // mise à jour des cookies
   201      Cookie.set("id_camp", this.logs.id_camp);
   202      Cookie.set("token", this.logs.token);
   203      Cookie.set("nom_camp", this.camp.nom_camp);
   204      Cookie.set("lien_compta", this.camp.lien_compta);
   205      Cookie.set("is_simple", this.camp.is_simple ? IsSimple : "");
   206    }
   207  
   208    onLoggout() {
   209      Cookie.remove("id_camp");
   210      Cookie.remove("token");
   211      Cookie.remove("nom_camp");
   212      Cookie.remove("lien_compta");
   213      Cookie.remove("is_simple");
   214      // vue-router ne permet pas de reset les routes,
   215      // passer d'un camp simple à un camp complet est donc problématique
   216      location.reload();
   217    }
   218  
   219    async getDetails<K extends keyof DetailsTypesOut>(categorie: K) {
   220      try {
   221        this.notifications.progress = true;
   222        const r: AxiosResponse<DetailsTypesOut[K]> = await Axios.get(
   223          BASE_URL + Directeurs.GetDetails(categorie),
   224          {
   225            auth: this.getAuth()
   226          }
   227        );
   228        this.logs.token = r.data.token;
   229        return r.data;
   230      } catch (error) {
   231        this.notifications.onAxiosError(error);
   232      }
   233      this.notifications.progress = false;
   234    }
   235  
   236    async updateDetails<K extends keyof DetailsTypesIn>(
   237      categorie: K,
   238      data: DetailsTypesIn[K]
   239    ) {
   240      try {
   241        this.notifications.progress = true;
   242        const r: AxiosResponse<DetailsTypesOut[K]> = await Axios.post(
   243          BASE_URL + Directeurs.UpdateDetails(categorie),
   244          data,
   245          {
   246            auth: this.getAuth()
   247          }
   248        );
   249        this.logs.token = r.data.token;
   250        return r.data;
   251      } catch (error) {
   252        this.notifications.onAxiosError(error);
   253      }
   254    }
   255  
   256    async addBonusDoc(file: File) {
   257      const formData = new FormData();
   258      formData.append("file", file, file.name);
   259      try {
   260        this.notifications.progress = true;
   261        const r: AxiosResponse<AddBonusDocOut> = await Axios.put(
   262          BASE_URL + Directeurs.AjouteBonusDoc,
   263          formData,
   264          {
   265            auth: this.getAuth()
   266          }
   267        );
   268        this.logs.token = r.data.token;
   269        return r.data.document;
   270      } catch (error) {
   271        this.notifications.onAxiosError(error);
   272      }
   273      this.notifications.progress = false;
   274    }
   275  
   276    async deleteDocument(idCrypted: string) {
   277      this.notifications.progress = true;
   278      try {
   279        await Axios.delete(UrlDocuments, {
   280          auth: this.getAuth(),
   281          params: { "id-crypted": idCrypted }
   282        });
   283        return true;
   284      } catch (error) {
   285        this.notifications.onAxiosError(error);
   286      }
   287      this.notifications.progress = false;
   288    }
   289  
   290    async uploadFile(file: File, idDocCrypted: string) {
   291      this.notifications.progress = true;
   292      const formData = new FormData();
   293      formData.append("file", file, file.name);
   294      formData.append("crypted-id", idDocCrypted);
   295      try {
   296        const out: AxiosResponse<PublicDocument> = await Axios.post(
   297          UrlDocuments,
   298          formData,
   299          {
   300            auth: this.getAuth()
   301          }
   302        );
   303        return out.data;
   304      } catch (error) {
   305        this.notifications.onAxiosError(error);
   306      }
   307      this.notifications.progress = false;
   308    }
   309  
   310    // ---------------------- Inscrits --------------------
   311  
   312    async getInscrits() {
   313      try {
   314        this.notifications.progress = true;
   315        const r: AxiosResponse<LoadInscritsOut> = await Axios.get(
   316          BASE_URL + Directeurs.GetInscrits,
   317          {
   318            auth: this.getAuth()
   319          }
   320        );
   321        this.logs.token = r.data.token;
   322        this.inscrits = r.data.inscrits || [];
   323        this.notifications.progress = false;
   324        return true;
   325      } catch (error) {
   326        this.notifications.onAxiosError(error);
   327      }
   328    }
   329  
   330    /** Filtre les messages en ne conservant que les messages perso (respo + centre),
   331     * par dossier
   332     */
   333    infosParticulieres() {
   334      const byFacture: { [key: number]: Inscrit[] } = {};
   335      this.inscrits.forEach(insc => {
   336        if (!insc.responsable.valide) return;
   337        const idDossier = insc.responsable.id;
   338        const l = byFacture[idDossier] || [];
   339        byFacture[idDossier] = l.concat(insc);
   340      });
   341      return Object.values(byFacture)
   342        .map(inscrits => {
   343          const first = inscrits[0]; // toutes les listes ont au moins un inscrits
   344          const messages = (first.responsable.messages || []).filter(
   345            m =>
   346              m.kind == MessageKind.MCentre || m.kind == MessageKind.MResponsable
   347          );
   348          const out: DossierMessages = {
   349            responsable: first.responsable,
   350            messages: messages,
   351            participants: inscrits
   352          };
   353          return out;
   354        })
   355        .filter(info => info.messages.length > 0)
   356        .sort((a, b) => a.responsable.nom.localeCompare(b.responsable.nom));
   357    }
   358  
   359    /** Renvoie l'ensemble des mails des inscrits (sans la liste d'attente)
   360     * Pour un camp complet, il s'agit des mails des responsables.
   361     * La deuxième liste contient les mails en copies des dossiers (vide pour un camp simple)
   362     */
   363    mailsInscrits() {
   364      const mails: { [key: string]: boolean } = {};
   365      const mailsCopie: { [key: string]: boolean } = {};
   366      C.inscrits.forEach(inscrit => {
   367        if (inscrit.is_attente) return;
   368        if (inscrit.mail) {
   369          mails[inscrit.mail] = true;
   370        }
   371        if (inscrit.responsable.mail) {
   372          mails[inscrit.responsable.mail] = true;
   373        }
   374        (inscrit.responsable.mails_copies || []).forEach(mail => {
   375          mailsCopie[mail] = true;
   376        });
   377      });
   378      // tri
   379      const mailsOut = Object.keys(mails).sort((a, b) => a.localeCompare(b));
   380      const mailsCopieOut = Object.keys(mailsCopie).sort((a, b) =>
   381        a.localeCompare(b)
   382      );
   383      return { mails: mailsOut, mailsCopie: mailsCopieOut };
   384    }
   385  
   386    private exportOneDossier(info: DossierMessages) {
   387      return (
   388        `------ ${Formatter.nomPrenom(info.responsable)} ------\n` +
   389        info.messages
   390          .map(m => {
   391            return m.contenu
   392              .split("\n")
   393              .filter(line => line.trim() != "")
   394              .join("\n");
   395          })
   396          .join("\n\n")
   397      );
   398    }
   399  
   400    async exportInfosToClipboard(infos: DossierMessages[]) {
   401      const data = infos.map(this.exportOneDossier).join("\n\n");
   402      try {
   403        await navigator.clipboard.writeText(data);
   404        this.notifications.success =
   405          "Situations particulières copiées dans le presse-papier.";
   406      } catch (err) {
   407        this.notifications.error = {
   408          code: 0,
   409          kind: "Accès au presse-papier",
   410          messageHtml: String(err)
   411        };
   412      }
   413    }
   414  
   415    async exportMailsToClipboard(mails: string) {
   416      try {
   417        await navigator.clipboard.writeText(mails);
   418        this.notifications.success =
   419          "Adresses mails copiées dans le presse-papier.";
   420      } catch (err) {
   421        this.notifications.error = {
   422          code: 0,
   423          kind: "Accès au presse-papier",
   424          messageHtml: String(err)
   425        };
   426      }
   427    }
   428  
   429    async updateInscrit(params: UpdateInscritIn) {
   430      try {
   431        this.notifications.progress = true;
   432        const r: AxiosResponse<LoadInscritsOut> = await Axios.post(
   433          BASE_URL + Directeurs.UpdateInscrit,
   434          params,
   435          {
   436            auth: this.getAuth()
   437          }
   438        );
   439        this.logs.token = r.data.token;
   440        this.inscrits = r.data.inscrits || [];
   441        this.notifications.progress = false;
   442        return true;
   443      } catch (error) {
   444        this.notifications.onAxiosError(error);
   445      }
   446    }
   447  
   448    async getContraintes() {
   449      try {
   450        this.notifications.progress = true;
   451        const r: AxiosResponse<LoadContraintesOut> = await Axios.get(
   452          BASE_URL + Directeurs.LoadContraintes,
   453          {
   454            auth: this.getAuth()
   455          }
   456        );
   457        this.logs.token = r.data.token;
   458        this.contraintes = r.data.contraintes || {};
   459        this.notifications.success = "Documents à remplir chargés.";
   460        return true;
   461      } catch (error) {
   462        this.notifications.onAxiosError(error);
   463      }
   464    }
   465  
   466    async createContrainte(contrainte: Contrainte) {
   467      try {
   468        this.notifications.progress = true;
   469        const r: AxiosResponse<LoadContraintesOut> = await Axios.put(
   470          BASE_URL + Directeurs.CreateContrainte,
   471          contrainte,
   472          {
   473            auth: this.getAuth()
   474          }
   475        );
   476        this.logs.token = r.data.token;
   477        this.contraintes = r.data.contraintes || {};
   478        this.notifications.success = "Documents à remplir bien ajouté.";
   479        return true;
   480      } catch (error) {
   481        this.notifications.onAxiosError(error);
   482      }
   483      this.notifications.progress = false;
   484    }
   485  
   486    async updateContrainte(contrainte: Contrainte) {
   487      const doc = this.contraintes[contrainte.id].document;
   488      try {
   489        this.notifications.progress = true;
   490        const r: AxiosResponse<UpdateContrainteOut> = await Axios.post(
   491          BASE_URL + Directeurs.CreateContrainte,
   492          contrainte,
   493          {
   494            auth: this.getAuth()
   495          }
   496        );
   497        this.logs.token = r.data.token;
   498        const ct: ContrainteComplete = { ...r.data.contrainte, document: doc };
   499        Vue.set(this.contraintes, r.data.contrainte.id, ct);
   500        this.notifications.success = "Demande mise à jour.";
   501        return true;
   502      } catch (error) {
   503        this.notifications.onAxiosError(error);
   504      }
   505      this.notifications.progress = false;
   506    }
   507  
   508    async deleteContrainte(id: number) {
   509      try {
   510        this.notifications.progress = true;
   511        const r: AxiosResponse<DeleteContrainteOut> = await Axios.delete(
   512          BASE_URL + Directeurs.DeleteContrainte,
   513          {
   514            auth: this.getAuth(),
   515            params: { id }
   516          }
   517        );
   518        this.logs.token = r.data.token;
   519        return r.data;
   520      } catch (error) {
   521        this.notifications.onAxiosError(error);
   522      }
   523      this.notifications.progress = false;
   524    }
   525  
   526    async lieDocumentContrainte(idContrainte: number) {
   527      try {
   528        this.notifications.progress = true;
   529        const r: AxiosResponse<LieDocumentOut> = await Axios.get(
   530          BASE_URL + Directeurs.LieDocument,
   531          {
   532            auth: this.getAuth(),
   533            params: { id: idContrainte }
   534          }
   535        );
   536        this.logs.token = r.data.token;
   537        this.contraintes[idContrainte].document = r.data.document;
   538        return r.data;
   539      } catch (error) {
   540        this.notifications.onAxiosError(error);
   541      }
   542      this.notifications.progress = false;
   543    }
   544  
   545    async getGroupes(notifie: boolean) {
   546      try {
   547        this.notifications.progress = true;
   548        const r: AxiosResponse<LoadGroupesOut> = await Axios.get(
   549          BASE_URL + Directeurs.LoadGroupes,
   550          {
   551            auth: this.getAuth()
   552          }
   553        );
   554        this.logs.token = r.data.token;
   555        this.groupes = r.data.groupes || {};
   556        this.campContraintes = r.data.camp_contraintes || [];
   557        this.groupeContraintes = r.data.groupe_contraintes || [];
   558        if (notifie) {
   559          this.notifications.success = "Groupes chargés.";
   560        }
   561      } catch (error) {
   562        this.notifications.onAxiosError(error);
   563      }
   564    }
   565  
   566    async createGroupe(nom: string, couleur: string) {
   567      const params: Groupe = {
   568        nom,
   569        id: -1,
   570        id_camp: -1,
   571        plage: { to: NullDate, from: NullDate },
   572        couleur: couleur
   573      };
   574      this.notifications.progress = true;
   575      try {
   576        const r: AxiosResponse<UpdateGroupeOut> = await Axios.put(
   577          BASE_URL + Directeurs.CreateGroupe,
   578          params,
   579          {
   580            auth: this.getAuth()
   581          }
   582        );
   583        this.logs.token = r.data.token;
   584        Vue.set(this.groupes, r.data.groupe.id, r.data.groupe); // VRC
   585        this.notifications.success = "Groupe ajouté.";
   586      } catch (error) {
   587        this.notifications.onAxiosError(error);
   588      }
   589    }
   590  
   591    async updateGroupe(groupe: Groupe) {
   592      try {
   593        this.notifications.progress = true;
   594        const r: AxiosResponse<UpdateGroupeOut> = await Axios.post(
   595          BASE_URL + Directeurs.UpdateGroupe,
   596          groupe,
   597          {
   598            auth: this.getAuth()
   599          }
   600        );
   601        this.logs.token = r.data.token;
   602        Vue.set(this.groupes, r.data.groupe.id, r.data.groupe); // VRC
   603        this.notifications.success = "Groupe modifié";
   604      } catch (error) {
   605        this.notifications.onAxiosError(error);
   606      }
   607    }
   608  
   609    async deleteGroupe(idGroupe: number) {
   610      try {
   611        this.notifications.progress = true;
   612        const r: AxiosResponse<LoadGroupesOut> = await Axios.delete(
   613          BASE_URL + Directeurs.DeleteGroupe,
   614          {
   615            auth: this.getAuth(),
   616            params: { id: idGroupe }
   617          }
   618        );
   619        this.logs.token = r.data.token;
   620        this.groupes = r.data.groupes || {};
   621        this.campContraintes = r.data.camp_contraintes || [];
   622        this.groupeContraintes = r.data.groupe_contraintes || [];
   623        this.notifications.success = "Groupe supprimé.";
   624      } catch (error) {
   625        this.notifications.onAxiosError(error);
   626      }
   627    }
   628  
   629    async updateGroupesPlages(plages: UpdatePlageIn) {
   630      try {
   631        this.notifications.progress = true;
   632        const r: AxiosResponse<UpdatePlageOut> = await Axios.post(
   633          BASE_URL + Directeurs.UpdatePlages,
   634          plages,
   635          {
   636            auth: this.getAuth()
   637          }
   638        );
   639        this.logs.token = r.data.token;
   640        this.notifications.progress = false;
   641        return r.data;
   642      } catch (error) {
   643        this.notifications.onAxiosError(error);
   644      }
   645    }
   646  
   647    async getGroupeAnimateurs(idGroupe: number) {
   648      try {
   649        this.notifications.progress = true;
   650        const r: AxiosResponse<LoadGroupeAnimateursOut> = await Axios.get(
   651          BASE_URL + Directeurs.LoadGroupeAnimateurs,
   652          {
   653            params: { id: idGroupe },
   654            auth: this.getAuth()
   655          }
   656        );
   657        this.notifications.progress = false;
   658        this.logs.token = r.data.token;
   659        return r.data;
   660      } catch (error) {
   661        this.notifications.onAxiosError(error);
   662      }
   663    }
   664  
   665    async addGroupeAnimateurs(idGroupe: number, idAnimateurs: number[]) {
   666      const params: AddGroupeAnimateursIn = {
   667        id_groupe: idGroupe,
   668        id_equipiers: idAnimateurs
   669      };
   670      try {
   671        this.notifications.progress = true;
   672        const r: AxiosResponse<LoadGroupeAnimateursOut> = await Axios.put(
   673          BASE_URL + Directeurs.AddGroupeAnimateurs,
   674          params,
   675          {
   676            auth: this.getAuth()
   677          }
   678        );
   679        this.logs.token = r.data.token;
   680        this.notifications.success = "Animateurs bien ajoutés au groupe.";
   681        return r.data;
   682      } catch (error) {
   683        this.notifications.onAxiosError(error);
   684      }
   685    }
   686  
   687    async deleteGroupeAnimateur(idGroupe: number, idAnimateur: number) {
   688      const params: DeleteGroupeAnimateurIn = {
   689        id_groupe: idGroupe,
   690        id_equipier: idAnimateur
   691      };
   692      try {
   693        this.notifications.progress = true;
   694        const r: AxiosResponse<LoadGroupeAnimateursOut> = await Axios.post(
   695          BASE_URL + Directeurs.DeleteGroupeAnimateur,
   696          params,
   697          {
   698            auth: this.getAuth()
   699          }
   700        );
   701        this.logs.token = r.data.token;
   702        this.notifications.success = "Animateur bien retiré du groupe.";
   703        return r.data;
   704      } catch (error) {
   705        this.notifications.onAxiosError(error);
   706      }
   707    }
   708  
   709    async updateInscritsAnimateur(params: UpdateInscritsAnimateurIn) {
   710      try {
   711        this.notifications.progress = true;
   712        const r: AxiosResponse<UpdateInsritsAnimateurOut> = await Axios.post(
   713          BASE_URL + Directeurs.UpdateInscritsAnimateur,
   714          params,
   715          {
   716            auth: this.getAuth()
   717          }
   718        );
   719        this.logs.token = r.data.token;
   720        this.notifications.success = "Animateur de référence mis à jour";
   721        return r.data.participant_equipiers;
   722      } catch (error) {
   723        this.notifications.onAxiosError(error);
   724      }
   725    }
   726  
   727    async autoRepartitInscritAnimateur(idGroupe: number) {
   728      try {
   729        this.notifications.progress = true;
   730        const r: AxiosResponse<UpdateInsritsAnimateurOut> = await Axios.put(
   731          BASE_URL + Directeurs.AutoRepartitInscritsAnimateur,
   732          {},
   733          { params: { "id-groupe": idGroupe }, auth: this.getAuth() }
   734        );
   735        this.logs.token = r.data.token;
   736        this.notifications.success = "Répartition effectuée.";
   737        return r.data.participant_equipiers;
   738      } catch (error) {
   739        this.notifications.onAxiosError(error);
   740      }
   741    }
   742  
   743    async updateGroupesContraintes(contraintes: DemandeContraintesIn) {
   744      try {
   745        this.notifications.progress = true;
   746        const r: AxiosResponse<LoadGroupesOut> = await Axios.post(
   747          BASE_URL + Directeurs.UpdateGroupesContraintes,
   748          contraintes,
   749          {
   750            auth: this.getAuth()
   751          }
   752        );
   753        this.logs.token = r.data.token;
   754        this.groupes = r.data.groupes || {};
   755        this.campContraintes = r.data.camp_contraintes || [];
   756        this.groupeContraintes = r.data.groupe_contraintes || [];
   757        this.notifications.progress = false;
   758        return true;
   759      } catch (error) {
   760        this.notifications.onAxiosError(error);
   761      }
   762    }
   763  
   764    async previewDocumentsInscrits(idContrainte: number) {
   765      try {
   766        const r: AxiosResponse<PreviewDocumentsParticipantsOut> = await Axios.get(
   767          BASE_URL + Directeurs.PreviewDocumentInscrits,
   768          {
   769            params: { "id-contrainte": idContrainte },
   770            auth: this.getAuth()
   771          }
   772        );
   773        return r.data;
   774      } catch (error) {
   775        this.notifications.onAxiosError(error);
   776      }
   777    }
   778  
   779    async downloadDocumentInscrits(idContrainte: OptionnalId) {
   780      this.notifications.setupMonitor();
   781      try {
   782        const r: AxiosResponse<Blob> = await Axios.post(
   783          BASE_URL + Directeurs.DownloadDocumentInscrits,
   784          idContrainte,
   785          {
   786            responseType: "arraybuffer",
   787            onDownloadProgress: this.notifications.updateMonitor,
   788            auth: this.getAuth()
   789          }
   790        );
   791        return downloadFile(r);
   792      } catch (error) {
   793        this.notifications.onAxiosError(error);
   794      }
   795    }
   796  
   797    async downloadFicheSanitaire(params: DownloadFicheSanitaireIn) {
   798      this.notifications.setupMonitor();
   799      try {
   800        const r: AxiosResponse<Blob> = await Axios.post(
   801          BASE_URL + Directeurs.DownloadFicheSanitaire,
   802          params,
   803          {
   804            responseType: "arraybuffer",
   805            auth: this.getAuth(),
   806            onDownloadProgress: this.notifications.updateMonitor
   807          }
   808        );
   809        return downloadFile(r);
   810      } catch (error) {
   811        this.notifications.onAxiosError(error);
   812      }
   813    }
   814  
   815    // -------------- Equipiers ------------------------
   816    async getEquipiers() {
   817      this.notifications.progress = true;
   818      try {
   819        const r: AxiosResponse<LoadEquipiersOut> = await Axios.get(
   820          BASE_URL + Directeurs.GetEquipe,
   821          {
   822            auth: this.getAuth()
   823          }
   824        );
   825        this.logs.token = r.data.token;
   826        return r.data;
   827      } catch (error) {
   828        this.notifications.onAxiosError(error);
   829      }
   830    }
   831  
   832    async rechercheProfil(params: PatternsSimilarite) {
   833      this.notifications.progress = true;
   834      try {
   835        const r: AxiosResponse<ChercheSimilaireOut> = await Axios.post(
   836          BASE_URL + Directeurs.RechercheProfil,
   837          params,
   838          {
   839            auth: this.getAuth()
   840          }
   841        );
   842        this.logs.token = r.data.token;
   843        return r.data;
   844      } catch (error) {
   845        this.notifications.onAxiosError(error);
   846      }
   847      this.notifications.progress = false;
   848    }
   849  
   850    async ajouteEquier(params: CreateEquipierIn) {
   851      this.notifications.progress = true;
   852      try {
   853        const r: AxiosResponse<LoadEquipiersOut> = await Axios.put(
   854          BASE_URL + Directeurs.AddEquipier,
   855          params,
   856          {
   857            auth: this.getAuth()
   858          }
   859        );
   860        this.logs.token = r.data.token;
   861        return r.data;
   862      } catch (error) {
   863        this.notifications.onAxiosError(error);
   864      }
   865      this.notifications.progress = false;
   866    }
   867  
   868    async updateEquipier(params: EquipierDirecteur) {
   869      this.notifications.progress = true;
   870      try {
   871        const r: AxiosResponse<LoadEquipiersOut> = await Axios.post(
   872          BASE_URL + Directeurs.ModifieEquipier,
   873          params,
   874          {
   875            auth: this.getAuth()
   876          }
   877        );
   878        this.logs.token = r.data.token;
   879        return r.data;
   880      } catch (error) {
   881        this.notifications.onAxiosError(error);
   882      }
   883    }
   884  
   885    async deleteEquipier(id: number) {
   886      this.notifications.progress = true;
   887      try {
   888        const r: AxiosResponse<LoadEquipiersOut> = await Axios.delete(
   889          BASE_URL + Directeurs.DeleteEquipier,
   890          {
   891            params: { id },
   892            auth: this.getAuth()
   893          }
   894        );
   895        this.logs.token = r.data.token;
   896        return r.data;
   897      } catch (error) {
   898        this.notifications.onAxiosError(error);
   899      }
   900    }
   901  
   902    async getDocumentsEquipe() {
   903      this.notifications.progress = true;
   904      try {
   905        const r: AxiosResponse<DocumentsEquipeOut> = await Axios.get(
   906          BASE_URL + Directeurs.GetDocumentsEquipe,
   907          {
   908            auth: this.getAuth()
   909          }
   910        );
   911        this.logs.token = r.data.token;
   912        return r.data;
   913      } catch (error) {
   914        this.notifications.onAxiosError(error);
   915      }
   916    }
   917  
   918    async updateDocumentEquipier(params: UpdateContrainteEquipierIn) {
   919      this.notifications.progress = true;
   920      try {
   921        await Axios.post(BASE_URL + Directeurs.SetDocumentsEquipe, params, {
   922          auth: this.getAuth()
   923        });
   924        return true;
   925      } catch (error) {
   926        this.notifications.onAxiosError(error);
   927      }
   928    }
   929  
   930    async addDocumentEquipe(file: File, params: AddDocumentIn) {
   931      this.notifications.progress = true;
   932      const formData = new FormData();
   933      formData.append("file", file, file.name);
   934      formData.append("meta", JSON.stringify(params));
   935      try {
   936        const r: AxiosResponse<AddDocumentOut> = await Axios.put(
   937          BASE_URL + Directeurs.AddDocumentEquipe,
   938          formData,
   939          {
   940            auth: this.getAuth()
   941          }
   942        );
   943        this.logs.token = r.data.token;
   944        return r.data.document;
   945      } catch (error) {
   946        this.notifications.onAxiosError(error);
   947      }
   948    }
   949  
   950    async donwloadDocumentsEquipe(onlyRequis: boolean) {
   951      this.notifications.setupMonitor();
   952      try {
   953        const r: AxiosResponse<Blob> = await Axios.get(
   954          BASE_URL + Directeurs.DownloadDocumentsEquipe,
   955          {
   956            params: { "only-requis": onlyRequis ? "true" : "" },
   957            responseType: "arraybuffer",
   958            onDownloadProgress: this.notifications.updateMonitor,
   959            auth: this.getAuth()
   960          }
   961        );
   962        return downloadFile(r);
   963      } catch (error) {
   964        this.notifications.onAxiosError(error);
   965      }
   966    }
   967  
   968    async inviteFormulaireEquipier(
   969      mode: "all" | "new" | "one",
   970      idParticipant: number
   971    ) {
   972      this.notifications.progress = true;
   973      const params: InviteFormulaireIn = { id_participant: idParticipant, mode };
   974      try {
   975        const r: AxiosResponse<LoadEquipiersOut> = await Axios.post(
   976          BASE_URL + Directeurs.InviteFormulaireEquipier,
   977          params,
   978          {
   979            auth: this.getAuth()
   980          }
   981        );
   982        this.logs.token = r.data.token;
   983        return r.data;
   984      } catch (error) {
   985        this.notifications.onAxiosError(error);
   986      }
   987    }
   988  
   989    // -------------- Exports ---------------------------
   990  
   991    async export(
   992      categorie: "inscrits" | "equipe" | "finances",
   993      options: OptionsExportInscrit
   994    ) {
   995      this.notifications.progress = true;
   996      try {
   997        const r: AxiosResponse<Blob> = await Axios.get(
   998          BASE_URL + Directeurs.ExportsExcel(categorie),
   999          {
  1000            params: {
  1001              bus: options.bus || "",
  1002              with_groupe: options.with_groupe ? "ok" : "",
  1003              with_attente: options.with_attente ? "ok" : "",
  1004              show_colors: options.show_colors ? "ok" : "",
  1005              simple: options.simple ? "ok" : ""
  1006            },
  1007            responseType: "arraybuffer",
  1008            auth: this.getAuth()
  1009          }
  1010        );
  1011        return downloadFile(r);
  1012      } catch (error) {
  1013        this.notifications.onAxiosError(error);
  1014      }
  1015    }
  1016  
  1017    // --------------Lettre du directeur ----------------
  1018  
  1019    async getLettreDirecteur() {
  1020      this.notifications.progress = true;
  1021      try {
  1022        const r: AxiosResponse<LettreDirecteurOut> = await Axios.get(
  1023          BASE_URL + Directeurs.GetLettreDirecteur,
  1024          {
  1025            auth: this.getAuth()
  1026          }
  1027        );
  1028        this.logs.token = r.data.token;
  1029        return r.data;
  1030      } catch (error) {
  1031        this.notifications.onAxiosError(error);
  1032      }
  1033      this.notifications.progress = false;
  1034    }
  1035  
  1036    async updateLettreDirecteur(params: Lettredirecteur) {
  1037      this.notifications.progress = true;
  1038      try {
  1039        const r: AxiosResponse<LettreDirecteurOut> = await Axios.post(
  1040          BASE_URL + Directeurs.UpdateLettreDirecteur,
  1041          params,
  1042          {
  1043            auth: this.getAuth()
  1044          }
  1045        );
  1046        this.logs.token = r.data.token;
  1047        return r.data;
  1048      } catch (error) {
  1049        this.notifications.onAxiosError(error);
  1050      }
  1051      this.notifications.progress = false;
  1052    }
  1053  
  1054    // ------------ Liste de vêtements ------------------
  1055  
  1056    async getListeVetements(saison: "ete" | "hiver" | "current") {
  1057      this.notifications.progress = true;
  1058      try {
  1059        const r: AxiosResponse<ListeVetementsOut> = await Axios.get(
  1060          BASE_URL + Directeurs.GetListeVetements(saison),
  1061          {
  1062            auth: this.getAuth()
  1063          }
  1064        );
  1065        this.logs.token = r.data.token;
  1066        return r.data;
  1067      } catch (error) {
  1068        this.notifications.onAxiosError(error);
  1069      }
  1070      this.notifications.progress = false;
  1071    }
  1072  
  1073    async updateListeVetements(params: ListeVetements) {
  1074      this.notifications.progress = true;
  1075      try {
  1076        const r: AxiosResponse<ListeVetementsOut> = await Axios.post(
  1077          BASE_URL + Directeurs.UpdateListeVetements,
  1078          params,
  1079          {
  1080            auth: this.getAuth()
  1081          }
  1082        );
  1083        this.logs.token = r.data.token;
  1084        return r.data;
  1085      } catch (error) {
  1086        this.notifications.onAxiosError(error);
  1087      }
  1088      this.notifications.progress = false;
  1089    }
  1090  
  1091    async previewListeVetements() {
  1092      this.notifications.progress = true;
  1093      try {
  1094        const r: AxiosResponse<ArrayBuffer> = await Axios.get(
  1095          BASE_URL + Directeurs.PreviewListeVetements,
  1096          {
  1097            responseType: "arraybuffer",
  1098            auth: this.getAuth()
  1099          }
  1100        );
  1101        return r.data;
  1102      } catch (error) {
  1103        this.notifications.onAxiosError(error);
  1104      }
  1105      this.notifications.progress = false;
  1106    }
  1107  
  1108    // ------------ JOOMEO ------------------------------
  1109  
  1110    async getPhotos() {
  1111      this.notifications.progress = true;
  1112      try {
  1113        const r: AxiosResponse<LoadJoomeoOut> = await Axios.get(
  1114          BASE_URL + Directeurs.GetJoomeo,
  1115          {
  1116            auth: this.getAuth()
  1117          }
  1118        );
  1119        this.logs.token = r.data.token;
  1120        return r.data;
  1121      } catch (error) {
  1122        this.notifications.onAxiosError(error);
  1123      }
  1124      this.notifications.progress = false;
  1125    }
  1126  
  1127    async setUploader(contactid: string) {
  1128      this.notifications.progress = true;
  1129      try {
  1130        const params: SetContactUploaderIn = { contactid };
  1131        const r: AxiosResponse<SetContactUploaderOut> = await Axios.post(
  1132          BASE_URL + Directeurs.SetContactUploader,
  1133          params,
  1134          {
  1135            auth: this.getAuth()
  1136          }
  1137        );
  1138        this.logs.token = r.data.token;
  1139        return r.data;
  1140      } catch (error) {
  1141        this.notifications.onAxiosError(error);
  1142      }
  1143      this.notifications.progress = false;
  1144    }
  1145  
  1146    async addContacts(params: AddContactJoomeoIn) {
  1147      this.notifications.progress = true;
  1148      try {
  1149        const r: AxiosResponse<AddContactJoomeoOut> = await Axios.put(
  1150          BASE_URL + Directeurs.AddContactsJoomeo,
  1151          params,
  1152          {
  1153            auth: this.getAuth()
  1154          }
  1155        );
  1156        this.logs.token = r.data.token;
  1157        return r.data;
  1158      } catch (error) {
  1159        this.notifications.onAxiosError(error);
  1160      }
  1161      this.notifications.progress = false;
  1162    }
  1163  
  1164    async deleteContact(contactid: string) {
  1165      this.notifications.progress = true;
  1166      try {
  1167        const r: AxiosResponse<DeleteContactOut> = await Axios.delete(
  1168          BASE_URL + Directeurs.DeleteContact,
  1169          {
  1170            params: { contactid },
  1171            auth: this.getAuth()
  1172          }
  1173        );
  1174        this.logs.token = r.data.token;
  1175        return r.data;
  1176      } catch (error) {
  1177        this.notifications.onAxiosError(error);
  1178      }
  1179      this.notifications.progress = false;
  1180    }
  1181  
  1182    async loadSondages() {
  1183      this.notifications.progress = true;
  1184      try {
  1185        const r: AxiosResponse<LoadSondagesOut> = await Axios.get(
  1186          BASE_URL + Directeurs.LoadSondages,
  1187          {
  1188            auth: this.getAuth()
  1189          }
  1190        );
  1191        this.logs.token = r.data.token;
  1192        this.notifications.progress = false;
  1193        return r.data.sondages || [];
  1194      } catch (error) {
  1195        this.notifications.onAxiosError(error);
  1196      }
  1197    }
  1198  }
  1199  
  1200  export const C = new Controller();
  1201  
  1202  // additionnal typing
  1203  interface DetailsTypesIn {
  1204    details: DetailsWritable;
  1205    envois: Envois;
  1206  }
  1207  
  1208  interface DetailsTypesOut {
  1209    details: DetailsDetailsOutput;
  1210    envois: DetailsEnvoisOut;
  1211  }
  1212  
  1213  export type LogginData = Omit<LogginOut, "camp" | "valide"> & {
  1214    camp: { label: string; is_simple: boolean };
  1215  };
  1216  
  1217  export interface OptionsExportInscrit {
  1218    simple?: boolean;
  1219    bus?: Bus;
  1220    with_groupe?: boolean;
  1221    with_attente?: boolean;
  1222    show_colors?: boolean;
  1223  }