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 }