import * as fs from 'fs'; const pdfjsLib = require('pdfjs-dist'); async function pdf_parse(travel: string) { interface product_details { quantity: number; price_ht: number; tva: string; } interface res { brand: string; purchase_date: string; products: { [product_name: string]: product_details; }; } const product_list: { [key: string]: product_details } = {}; let supplier = ''; let date = ''; const pdf_path = travel; try { // Lecture du fichier binaire du PDF et conversion pour PDF.js const data_buffer = new Uint8Array(fs.readFileSync(pdf_path)); // Chargement du document par PDF.js const loading_task = pdfjsLib.getDocument({ data: data_buffer }); const pdf = await loading_task.promise; let text = ''; // Boucle pour extraire le text de chaque page du PDF for (let i = 1; i <= pdf.numPages; i++) { const page = await pdf.getPage(i); const text_content = await page.getTextContent(); // On récupère chaque fragment de text trouvé graphiquement sur la page et on les sépare par un saut de ligne const text_page = text_content.items.map((item: any) => item.str).join('\n'); text += text_page + '\n'; } const regex_auchan = /auchan/i.test(text); // on regarde si c'est auchan ou metro if (regex_auchan) { supplier = "Auchan"; // on regarde la date d'achat avec une expression reguliere pour auchan const regex_date = /(\d{2})\/(\d{2})\/(\d{4})/; const corres = text.match(regex_date); if (corres) { date = corres[0] } else { date = "non trouvé" } // Découpage en lignes pour l'analyse et cration d'un tableau de toutes les lignes const lines = text.split('\n').map(l => l.trim()).filter(l => l.length > 0); // Algorithme de recherche verticale pour Auchan for (let i = 0; i < lines.length; i++) { // Si la ligne correspond exactement à un code-barres à 13 chiffres if (/^\d{13}$/.test(lines[i])) { const product_name = lines[i + 1]; const qte = lines[i + 3]; const price = lines[i + 4]; const tva = lines[i + 5]; product_list[product_name] = { quantity: parseInt(qte, 10), price_ht: parseFloat(price.replace(',', '.')), tva: tva.replace(',', '.').trim() + "%" }; } } } else { supplier = "METRO"; // on regarde la date d'achat avec une expression reguliere pour metro const regex_date = /(\d{2})-(\d{2})-(\d{4})/; const corres = text.match(regex_date); if (corres) { date = corres[0]; } else { date = "non trouvé"; } // Découpage en lignes pour l'analyse et cration d'un tableau de toutes les lignes const lines = text.split('\n').map(l => l.trim()).filter(l => l.length > 0); // Algorithme de recherche verticale pour metro for (let i = 0; i < lines.length; i++) { // Si la ligne correspond exactement à un code-barres à 13 chiffres if (/^\d{13}$/.test(lines[i])) { const product_name = lines[i + 1]; const qte = lines[i + 4]; const price = lines[i + 5]; const tva = lines[i + 6]; let tva_final = ""; if (tva == "B"){ tva_final = "5.5%"; } else { tva_final = "20%"; } product_list[product_name] = { quantity: parseInt(qte, 10), price_ht: parseFloat(price.replace(',', '.')), tva: tva_final }; } } } // Construction de l'objet final const result: res = { brand: supplier, purchase_date: date, products: product_list }; console.log(result); return result; } catch (e) { console.error("Erreur :", e); } } export default pdf_parse;