From 63cff880a5483ce31c8ba4fd189f3f65d27b288e Mon Sep 17 00:00:00 2001 From: Peacock Date: Fri, 27 Feb 2026 12:04:49 +0100 Subject: [PATCH] feat: handle duplicates with file source info (v1.0.1.1) --- manifest.prod.xml | 2 +- manifest.xml | 8 ++-- src/taskpane/components/App.tsx | 1 + src/taskpane/excelLogic.ts | 66 +++++++++++++++++++++++++++++++-- src/taskpane/models.ts | 2 + 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/manifest.prod.xml b/manifest.prod.xml index 7148fd3..da38a63 100644 --- a/manifest.prod.xml +++ b/manifest.prod.xml @@ -1,7 +1,7 @@ 2c37abde-33e4-4624-b95a-a0aed1526f1b - 1.0.1.0 + 1.0.1.1 SAT Elektrotechnik GmbH de-DE diff --git a/manifest.xml b/manifest.xml index f0affbf..7fbd613 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,10 +1,10 @@ 2c37abde-33e4-4624-b95a-a0aed1526f1b - 1.0.1.0 + 1.0.1.1 SAT Elektrotechnik GmbH de-DE - + @@ -73,8 +73,8 @@ - - + + diff --git a/src/taskpane/components/App.tsx b/src/taskpane/components/App.tsx index 009159f..656df87 100644 --- a/src/taskpane/components/App.tsx +++ b/src/taskpane/components/App.tsx @@ -39,6 +39,7 @@ const App: React.FC = () => { colorNew: "#d4edda", // light green colorChanged: "#fff3cd", // light yellow/orange colorDeleted: "#f8d7da", // light red + colorDuplicate: "#ff0000ff", // light orange for duplicates }); useEffect(() => { diff --git a/src/taskpane/excelLogic.ts b/src/taskpane/excelLogic.ts index d1a8b08..18c625e 100644 --- a/src/taskpane/excelLogic.ts +++ b/src/taskpane/excelLogic.ts @@ -120,6 +120,7 @@ function buildSheetMappingStatus(sheetInfo: SheetInfo, headerRow: any[], rowInde availableColumns, mappings, isExternal: sheetInfo.isExternal, + fileName: sheetInfo.fileName, externalData: sheetInfo.externalData }; } @@ -187,16 +188,43 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings: } } - // Zusatzfelder für die Kabelliste: Länge, gezogen am, von (Monteur) + // Zusatzfelder für die Kabelliste: Länge, gezogen am, von (Monteur), Bemerkung consolidatedRow.push(""); consolidatedRow.push(""); consolidatedRow.push(""); + // Wir speichern temporär die Quelle in der letzten Spalte, um sie später für Duplikate zu nutzen + const sourceInfo = mapping.isExternal ? `${mapping.fileName || 'Externe Datei'} - ${mapping.sheetName}` : mapping.sheetName; + consolidatedRow.push(sourceInfo); + finalData.push(consolidatedRow); rowsConsolidated++; } } + // --- DUPLIKAT PRÜFUNG --- + const cableCountMap = new Map(); + // Finde heraus, wie oft jede Kabelnummer vorkommt + for (const row of finalData) { + const kNr = String(row[0] || "").trim(); + if (kNr) { + cableCountMap.set(kNr, (cableCountMap.get(kNr) || 0) + 1); + } + } + + // Schreibe "Duplikat" inkl. Quelle in die Bemerkungs-Spalte, ansonsten leere die Spalte wieder + for (const row of finalData) { + const kNr = String(row[0] || "").trim(); + const sourceInfo = row[row.length - 1]; // Temporär gespeicherte Info abrufen + + if (kNr && (cableCountMap.get(kNr) || 0) > 1) { + row[row.length - 1] = `Duplikat (aus: ${sourceInfo})`; + } else { + row[row.length - 1] = ""; // Nur Duplikate erhalten einen Eintrag in "Bemerkung" + } + } + // --- ENDE DUPLIKAT PRÜFUNG --- + // Prüfen, ob "Kabelliste" existiert let targetSheet: Excel.Worksheet; let listExists = false; @@ -209,7 +237,7 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings: listExists = false; } - const fullHeaders = [...TARGET_COLUMNS.map(tc => tc.id), "Länge", "gezogen am", "von (Monteur)"]; + const fullHeaders = [...TARGET_COLUMNS.map(tc => tc.id), "Länge", "gezogen am", "von (Monteur)", "Bemerkung"]; if (listExists) { try { @@ -223,6 +251,7 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings: const formatChangedQueue: { row: number, col: number }[] = []; const formatDeletedQueue: number[] = []; + const formatDuplicateQueue: number[] = []; // NEU: Queue für Duplikate const incomingMap = new Map(); for (const row of finalData) { @@ -252,6 +281,16 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings: formatChangedQueue.push({ row: r, col: c }); } } + + // Prüfen ob Bemerkung aktualisiert werden muss (z.B. neues Duplikat) + const bemerkungColIndex = fullHeaders.length - 1; + const inBemerkung = String(inVals[bemerkungColIndex] || "").trim(); + existingValues[r][bemerkungColIndex] = inBemerkung; + + if (inBemerkung.startsWith("Duplikat")) { + formatDuplicateQueue.push(r); + } + incomingMap.delete(kNr); } else { // Entfallen @@ -295,7 +334,19 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings: // Neue Zeilen markieren for (let i = 0; i < newRows.length; i++) { - currentBody.getRow(newRowsStartIndex + i).format.fill.color = settings.colorNew; + const rowIndex = newRowsStartIndex + i; + const rowData = newRows[i]; + + if (String(rowData[fullHeaders.length - 1]).trim().startsWith("Duplikat")) { + currentBody.getRow(rowIndex).format.fill.color = settings.colorDuplicate; + } else { + currentBody.getRow(rowIndex).format.fill.color = settings.colorNew; + } + } + + // Bestehende Duplikat-Zeilen markieren + for (const rowIndex of formatDuplicateQueue) { + currentBody.getRow(rowIndex).format.fill.color = settings.colorDuplicate; } table.getRange().format.autofitColumns(); @@ -335,6 +386,15 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings: // Markiere komplett neu entfernt auf Userwunsch + // Duplikate beim Neu-Erstellen einfärben: + const bodyRange = table.getDataBodyRange(); + + for (let i = 0; i < finalData.length; i++) { + if (String(finalData[i][fullHeaders.length - 1]).trim().startsWith("Duplikat")) { + bodyRange.getRow(i).format.fill.color = settings.colorDuplicate; + } + } + targetRange.format.autofitColumns(); await context.sync(); diff --git a/src/taskpane/models.ts b/src/taskpane/models.ts index 91a3e32..daca6a6 100644 --- a/src/taskpane/models.ts +++ b/src/taskpane/models.ts @@ -17,6 +17,7 @@ export interface SheetMappingStatus { mappings: ColumnMappingInfo[]; availableColumns: { name: string; index: number }[]; isExternal?: boolean; + fileName?: string; externalData?: any[][]; } @@ -29,6 +30,7 @@ export interface ConsolidateSettings { colorNew: string; colorChanged: string; colorDeleted: string; + colorDuplicate: string; } export const TARGET_COLUMNS: TargetColumnDef[] = [