mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 12:35:24 +02:00
fix: read all sheets in Traffic Weekly Excel for complete GV data
processTrafficExcel was only reading the first sheet, missing data from year-based sheets (e.g., "2025", "2026"). Now iterates all sheets with auto-detection of column layout, matching the processAdsExcel pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a1dcb9b9fc
commit
31ad7fda21
+53
-33
@@ -506,46 +506,66 @@ export const processTrafficExcel = async (fileOrBuffer: File | ArrayBuffer): Pro
|
||||
const workbook = XLSX.read(arrayBuffer, { type: 'array' });
|
||||
const allData: TrafficRecord[] = [];
|
||||
|
||||
// Process first sheet only (Traffic Weekly.xlsx typically has one sheet)
|
||||
const sheetName = workbook.SheetNames[0];
|
||||
const worksheet = workbook.Sheets[sheetName];
|
||||
const jsonData: any[][] = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: "" });
|
||||
// Process ALL sheets (e.g., "2025", "2026") - same pattern as processAdsExcel
|
||||
for (const sheetName of workbook.SheetNames) {
|
||||
const worksheet = workbook.Sheets[sheetName];
|
||||
const jsonData: any[][] = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: "" });
|
||||
|
||||
console.log(`Processing Traffic sheet "${sheetName}": ${jsonData.length} rows`);
|
||||
console.log(`Processing Traffic sheet "${sheetName}": ${jsonData.length} rows`);
|
||||
|
||||
// Column mapping for Traffic Weekly.xlsx:
|
||||
// A (0): Year
|
||||
// B (1): Week
|
||||
// C (2): ASIN
|
||||
// F (5): Country
|
||||
// G (6): Glance Views (GV)
|
||||
// Detect if sheet name is a valid year (multi-sheet format)
|
||||
const sheetYear = parseInt(sheetName);
|
||||
const isYearSheet = !isNaN(sheetYear) && sheetYear >= 2020 && sheetYear <= 2100;
|
||||
|
||||
// Skip header row (index 0), process data rows
|
||||
for (let i = 1; i < jsonData.length; i++) {
|
||||
const row = jsonData[i];
|
||||
if (!row || row.length < 7) continue;
|
||||
// Auto-detect column layout from header row
|
||||
const headerRow = jsonData[0];
|
||||
if (!headerRow) continue;
|
||||
|
||||
const yearRaw = row[0];
|
||||
const weekRaw = row[1];
|
||||
const asin = row[2];
|
||||
const countryRaw = row[5];
|
||||
const gvRaw = row[6];
|
||||
const headers = headerRow.map((h: any) => String(h).trim().toLowerCase());
|
||||
let yearIdx = headers.findIndex((h: string) => h === 'year' || h === 'año');
|
||||
let weekIdx = headers.findIndex((h: string) => h === 'week' || h === 'semana');
|
||||
let asinIdx = headers.findIndex((h: string) => h === 'asin');
|
||||
let countryIdx = headers.findIndex((h: string) => h === 'country' || h === 'país' || h === 'pais' || h === 'marketplace');
|
||||
let gvIdx = headers.findIndex((h: string) => h.includes('glance') || h === 'gv' || h.includes('page view'));
|
||||
|
||||
// Skip if missing essential data
|
||||
if (!asin || yearRaw === undefined || weekRaw === undefined || !countryRaw) continue;
|
||||
// Fallback to positional mapping if headers not found
|
||||
if (asinIdx === -1 || countryIdx === -1 || gvIdx === -1) {
|
||||
if (isYearSheet) {
|
||||
// Year-based sheets: no year column
|
||||
weekIdx = 0; asinIdx = 1; countryIdx = 4; gvIdx = 5; yearIdx = -1;
|
||||
} else {
|
||||
// Single sheet with year column
|
||||
yearIdx = 0; weekIdx = 1; asinIdx = 2; countryIdx = 5; gvIdx = 6;
|
||||
}
|
||||
}
|
||||
|
||||
const year = parseInt(String(yearRaw));
|
||||
const weekNum = parseInt(String(weekRaw));
|
||||
if (isNaN(year) || year < 2020 || year > 2100) continue;
|
||||
if (isNaN(weekNum) || weekNum < 1 || weekNum > 53) continue;
|
||||
const minCols = Math.max(asinIdx, countryIdx, gvIdx) + 1;
|
||||
|
||||
allData.push({
|
||||
country: mapCountryToMarketplace(String(countryRaw)),
|
||||
year,
|
||||
week: weekNum,
|
||||
asin: String(asin).trim().toUpperCase(),
|
||||
glanceViews: parseUnits(String(gvRaw)),
|
||||
});
|
||||
for (let i = 1; i < jsonData.length; i++) {
|
||||
const row = jsonData[i];
|
||||
if (!row || row.length < minCols) continue;
|
||||
|
||||
const yearRaw = isYearSheet ? sheetYear : (yearIdx >= 0 ? row[yearIdx] : undefined);
|
||||
const weekRaw = weekIdx >= 0 ? row[weekIdx] : undefined;
|
||||
const asin = row[asinIdx];
|
||||
const countryRaw = row[countryIdx];
|
||||
const gvRaw = row[gvIdx];
|
||||
|
||||
if (!asin || yearRaw === undefined || weekRaw === undefined || !countryRaw) continue;
|
||||
|
||||
const year = typeof yearRaw === 'number' ? yearRaw : parseInt(String(yearRaw));
|
||||
const weekNum = parseInt(String(weekRaw));
|
||||
if (isNaN(year) || year < 2020 || year > 2100) continue;
|
||||
if (isNaN(weekNum) || weekNum < 1 || weekNum > 53) continue;
|
||||
|
||||
allData.push({
|
||||
country: mapCountryToMarketplace(String(countryRaw)),
|
||||
year,
|
||||
week: weekNum,
|
||||
asin: String(asin).trim().toUpperCase(),
|
||||
glanceViews: parseUnits(String(gvRaw)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Total Traffic records loaded: ${allData.length}`);
|
||||
|
||||
Reference in New Issue
Block a user