resanomaliedoublejustifavecqrcode
This commit is contained in:
@@ -2091,50 +2091,63 @@ app.post('/api/notes', authenticateToken, upload.any(), async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
// ── QR par ligne : téléchargement + upload en parallèle ──────────
|
||||
await Promise.all(
|
||||
lignesParsed.map(async (ligne, i) => {
|
||||
const ligneQrRef = ligne.qrNoteRef;
|
||||
if (!ligneQrRef) return;
|
||||
try {
|
||||
const qrLigne = await pool.request()
|
||||
.input('noteRef', sql.NVarChar, ligneQrRef)
|
||||
.query(`SELECT TOP 1 fichiers FROM UploadTokens WHERE noteRef = @noteRef AND used = 1 ORDER BY expiresAt DESC`);
|
||||
if (!qrLigne.recordset.length || !qrLigne.recordset[0].fichiers) {
|
||||
console.warn(`⚠️ QR ligne ${i} (${ligneQrRef}) : token introuvable ou non utilisé`);
|
||||
return;
|
||||
}
|
||||
const qrFichiers = JSON.parse(qrLigne.recordset[0].fichiers);
|
||||
if (!ligne.qrFiles) ligne.qrFiles = [];
|
||||
// ── QR par ligne : ne re-télécharge/ré-upload que si le client n'a pas déjà le fichier ──
|
||||
await Promise.all(
|
||||
lignesParsed.map(async (ligne, i) => {
|
||||
const ligneQrRef = ligne.qrNoteRef;
|
||||
if (!ligneQrRef) return;
|
||||
|
||||
await Promise.all(
|
||||
qrFichiers.map(async f => {
|
||||
try {
|
||||
const buf = await downloadFromSharePoint(f.uploadUrl);
|
||||
const fileObj = {
|
||||
buffer: buf,
|
||||
originalname: f.fileName,
|
||||
mimetype: f.fileName?.endsWith('.pdf') ? 'application/pdf' : 'image/jpeg',
|
||||
size: buf.length
|
||||
};
|
||||
allFiles.push(fileObj);
|
||||
// ✅ Si le client a déjà reçu ce fichier via le polling QR (origin 'qr'),
|
||||
// il est déjà dans ligne.qrFiles avec son uploadUrl d'origine.
|
||||
// Pas besoin de re-télécharger/ré-uploader : on évite ainsi le doublon
|
||||
// causé par un nouveau nom de fichier (basé sur la référence finale de la note).
|
||||
const dejaRecuParClient = Array.isArray(ligne.qrFiles) &&
|
||||
ligne.qrFiles.some(f => !f.origin || f.origin === 'qr');
|
||||
|
||||
const uploaded = await uploadToSharePointHierarchique(fileObj, reference, nomDossier, moisDossier);
|
||||
const dejaSauve = ligne.qrFiles.some(x => x.fileName === uploaded.fileName);
|
||||
if (!dejaSauve) {
|
||||
ligne.qrFiles.push({ fileName: uploaded.fileName, uploadUrl: uploaded.uploadUrl });
|
||||
}
|
||||
console.log(`✅ QR ligne ${i} stocké: ${uploaded.fileName}`);
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ QR ligne ${i} download/upload fail:`, e.message);
|
||||
if (dejaRecuParClient) {
|
||||
console.log(`✅ QR ligne ${i} (${ligneQrRef}) : fichier déjà reçu côté client, pas de re-upload`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const qrLigne = await pool.request()
|
||||
.input('noteRef', sql.NVarChar, ligneQrRef)
|
||||
.query(`SELECT TOP 1 fichiers FROM UploadTokens WHERE noteRef = @noteRef AND used = 1 ORDER BY expiresAt DESC`);
|
||||
if (!qrLigne.recordset.length || !qrLigne.recordset[0].fichiers) {
|
||||
console.warn(`⚠️ QR ligne ${i} (${ligneQrRef}) : token introuvable ou non utilisé`);
|
||||
return;
|
||||
}
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ QR ligne ${i} erreur DB:`, e.message);
|
||||
}
|
||||
})
|
||||
);
|
||||
const qrFichiers = JSON.parse(qrLigne.recordset[0].fichiers);
|
||||
if (!ligne.qrFiles) ligne.qrFiles = [];
|
||||
|
||||
await Promise.all(
|
||||
qrFichiers.map(async f => {
|
||||
try {
|
||||
const buf = await downloadFromSharePoint(f.uploadUrl);
|
||||
const fileObj = {
|
||||
buffer: buf,
|
||||
originalname: f.fileName,
|
||||
mimetype: f.fileName?.endsWith('.pdf') ? 'application/pdf' : 'image/jpeg',
|
||||
size: buf.length
|
||||
};
|
||||
allFiles.push(fileObj);
|
||||
|
||||
const uploaded = await uploadToSharePointHierarchique(fileObj, reference, nomDossier, moisDossier);
|
||||
const dejaSauve = ligne.qrFiles.some(x => x.fileName === uploaded.fileName);
|
||||
if (!dejaSauve) {
|
||||
ligne.qrFiles.push({ fileName: uploaded.fileName, uploadUrl: uploaded.uploadUrl });
|
||||
}
|
||||
console.log(`✅ QR ligne ${i} stocké: ${uploaded.fileName}`);
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ QR ligne ${i} download/upload fail:`, e.message);
|
||||
}
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ QR ligne ${i} erreur DB:`, e.message);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// ── Upload fichiers soumis directement par ligne (files_${depId}) ──
|
||||
// Identique à la logique du PUT /api/notes/brouillons/:id
|
||||
@@ -2534,28 +2547,37 @@ app.put('/api/notes/:id', authenticateToken, upload.any(), async (req, res) => {
|
||||
}
|
||||
|
||||
// QR par ligne
|
||||
for (let i = 0; i < lignesParsed.length; i++) {
|
||||
const ligneQrRef = lignesParsed[i].qrNoteRef;
|
||||
if (!ligneQrRef) continue;
|
||||
try {
|
||||
const qrLigne = await pool.request()
|
||||
.input('noteRef', sql.NVarChar, ligneQrRef)
|
||||
.query(`SELECT TOP 1 fichiers FROM UploadTokens WHERE noteRef = @noteRef AND used = 1 ORDER BY expiresAt DESC`);
|
||||
if (qrLigne.recordset.length && qrLigne.recordset[0].fichiers) {
|
||||
const qrFichiers = JSON.parse(qrLigne.recordset[0].fichiers);
|
||||
for (const f of qrFichiers) {
|
||||
try {
|
||||
const buf = await downloadFromSharePoint(f.uploadUrl);
|
||||
const r = await uploadToSharePointHierarchique(
|
||||
{ buffer: buf, originalname: f.fileName, mimetype: f.fileName?.endsWith('.pdf') ? 'application/pdf' : 'image/jpeg', size: buf.length },
|
||||
nouvelleReference, nomDossier, moisDossier
|
||||
);
|
||||
fichiersUploades.push(r);
|
||||
} catch (e) { console.warn(`⚠️ QR ligne ${i} download fail:`, e.message); }
|
||||
// QR par ligne — skip si le client a déjà le fichier (évite doublon)
|
||||
for (let i = 0; i < lignesParsed.length; i++) {
|
||||
const ligneQrRef = lignesParsed[i].qrNoteRef;
|
||||
if (!ligneQrRef) continue;
|
||||
|
||||
const dejaRecuParClient = Array.isArray(lignesParsed[i].qrFiles) &&
|
||||
lignesParsed[i].qrFiles.some(f => !f.origin || f.origin === 'qr');
|
||||
if (dejaRecuParClient) {
|
||||
console.log(`✅ [CAS1] QR ligne ${i} (${ligneQrRef}) : fichier déjà reçu côté client, pas de re-upload`);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const qrLigne = await pool.request()
|
||||
.input('noteRef', sql.NVarChar, ligneQrRef)
|
||||
.query(`SELECT TOP 1 fichiers FROM UploadTokens WHERE noteRef = @noteRef AND used = 1 ORDER BY expiresAt DESC`);
|
||||
if (qrLigne.recordset.length && qrLigne.recordset[0].fichiers) {
|
||||
const qrFichiers = JSON.parse(qrLigne.recordset[0].fichiers);
|
||||
for (const f of qrFichiers) {
|
||||
try {
|
||||
const buf = await downloadFromSharePoint(f.uploadUrl);
|
||||
const r = await uploadToSharePointHierarchique(
|
||||
{ buffer: buf, originalname: f.fileName, mimetype: f.fileName?.endsWith('.pdf') ? 'application/pdf' : 'image/jpeg', size: buf.length },
|
||||
nouvelleReference, nomDossier, moisDossier
|
||||
);
|
||||
fichiersUploades.push(r);
|
||||
} catch (e) { console.warn(`⚠️ QR ligne ${i} download fail:`, e.message); }
|
||||
}
|
||||
}
|
||||
} catch (e) { console.warn(`⚠️ QR ligne ${i} erreur DB:`, e.message); }
|
||||
}
|
||||
} catch (e) { console.warn(`⚠️ QR ligne ${i} erreur DB:`, e.message); }
|
||||
}
|
||||
|
||||
// lignesJsonCorrige APRÈS injection
|
||||
const lignesJsonCorrige = JSON.stringify(lignesParsed);
|
||||
|
||||
Reference in New Issue
Block a user