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

     1  import levenshtein from "js-levenshtein";
     2  import { EquipierDirecteur, Role } from "./types";
     3  import Vue from "vue";
     4  import { EditFields } from "./formatter";
     5  
     6  type keys = keyof EquipierDirecteur;
     7  type partialKeys = { [K in keys]?: boolean };
     8  
     9  // a synchroniser avec l'export excel du serveur
    10  const HEADER_EXCEL: keys[] = [
    11    "nom",
    12    "prenom",
    13    "roles",
    14    "diplome",
    15    "appro",
    16    "sexe",
    17    "nom_jeune_fille",
    18    "date_naissance",
    19    "departement_naissance",
    20    "ville_naissance",
    21    "mail",
    22    "tels",
    23    "adresse",
    24    "code_postal",
    25    "ville",
    26    "securite_sociale",
    27    "profession",
    28    "etudiant",
    29    "fonctionnaire",
    30    "presence"
    31  ];
    32  
    33  const RAW_FIELDS: partialKeys = {
    34    nom: true,
    35    prenom: true,
    36    nom_jeune_fille: true,
    37    ville_naissance: true,
    38    mail: true,
    39    adresse: true,
    40    ville: true,
    41    code_postal: true,
    42    securite_sociale: true,
    43    profession: true
    44  };
    45  
    46  const BOOL_FIELDS: partialKeys = { etudiant: true, fonctionnaire: true };
    47  
    48  const ENUM_FIELDS = { diplome: true, appro: true };
    49  
    50  function parseDate(s: string) {
    51    const reg = /(\d{1,2})[/\- ](\d{1,2})[/\- ](\d{2,4})/;
    52    const match = reg.exec(s);
    53    if (match == null) {
    54      return;
    55    }
    56    const day = Number(match[1]);
    57    const month = Number(match[2]);
    58    let year = Number(match[3]);
    59    if (year < 100) {
    60      year = year + 1900;
    61    }
    62    return { __date__: true, year, month, day };
    63  }
    64  
    65  function parseTels(s: string) {
    66    s.replace(" ", "");
    67    let sep = ";";
    68    if (s.includes(",")) {
    69      sep = ",";
    70    } else if (s.includes("/")) {
    71      sep = "/";
    72    }
    73    const t = s.split(sep);
    74    if (t.length > 0) {
    75      return t;
    76    }
    77  }
    78  
    79  function parseBool(s: string) {
    80    if (!s) {
    81      return;
    82    }
    83    return ["Oui", "O", "1"].indexOf(s) != -1;
    84  }
    85  
    86  function parseSexe(s: string) {
    87    if (["h", "homme", "m", "masculin", "g"].indexOf(s.toLowerCase()) != -1) {
    88      return "M";
    89    } else if (
    90      ["f", "femme", "féminin", "feminin"].indexOf(s.toLowerCase()) != -1
    91    ) {
    92      return "F";
    93    }
    94  }
    95  
    96  function parseEnum(s: string, targets: string[]) {
    97    s = s.toLowerCase().replace(" ", "");
    98    const scores = targets.map(t =>
    99      levenshtein(s, t.toLowerCase().replace(" ", ""))
   100    );
   101    const best = scores.indexOf(Math.min(...scores));
   102    const isExact = s == targets[best].toLowerCase().replace(" ", "");
   103    return { isExact, bestIndex: best };
   104  }
   105  
   106  function parseRoles(s: string) {
   107    const targets = EditFields.roles;
   108    const roles = s.split(" - ").map(rs => {
   109      const { bestIndex } = parseEnum(
   110        rs,
   111        targets.map(t => t.text)
   112      );
   113      return targets[bestIndex].value as Role;
   114    });
   115    return roles;
   116  }
   117  
   118  export function processClipboard(
   119    event: ClipboardEvent,
   120    target: EquipierDirecteur,
   121    approxMatched: { [K in keyof typeof ENUM_FIELDS]: boolean }
   122  ) {
   123    if (event.clipboardData == null) return;
   124    const cells = event.clipboardData
   125      .getData("text")
   126      .split("\n")[0] // first line : header
   127      .split("\t"); // columns
   128  
   129    if (cells.length < HEADER_EXCEL.length) {
   130      // fichier manisfestment invalide
   131      return;
   132    }
   133    event.preventDefault();
   134    HEADER_EXCEL.forEach((field, i) => {
   135      const textData = cells[i];
   136      if (RAW_FIELDS[field]) {
   137        if (textData) {
   138          Vue.set(target, field, textData);
   139        }
   140      } else if (field == "date_naissance") {
   141        const date = parseDate(textData);
   142        if (date) {
   143          Vue.set(target, "date_naissance", date);
   144        }
   145      } else if (field == "tels") {
   146        const tels = parseTels(textData);
   147        if (tels) {
   148          Vue.set(target, "tels", tels);
   149        }
   150      } else if (field == "sexe") {
   151        const sexe = parseSexe(textData);
   152        if (sexe) {
   153          Vue.set(target, "sexe", sexe);
   154        }
   155      } else if (field == "roles") {
   156        const roles = parseRoles(textData);
   157        if (roles) {
   158          Vue.set(target, "roles", roles);
   159        }
   160      } else if (BOOL_FIELDS[field]) {
   161        const v = parseBool(textData);
   162        if (v != undefined) {
   163          Vue.set(target, field, v);
   164        }
   165      } else if (ENUM_FIELDS[field as keyof typeof ENUM_FIELDS]) {
   166        const field_ = field as keyof typeof ENUM_FIELDS;
   167        if (textData) {
   168          const targets: { text: string; value: any }[] = EditFields[field_];
   169          const { isExact, bestIndex } = parseEnum(
   170            textData,
   171            targets.map(t => t.text)
   172          );
   173          Vue.set(target, field_, targets[bestIndex].value);
   174          Vue.set(approxMatched, field_, !isExact);
   175        }
   176      }
   177    });
   178  }