fix: resolve vendor data upload error by implementing client-side parsing and sequential batching

This commit is contained in:
Christian Vidal Wolf
2026-02-20 13:32:26 +01:00
parent a8258398f7
commit 85c789bf52
5 changed files with 162 additions and 65 deletions
+51 -1
View File
@@ -1,7 +1,57 @@
import { SalesRecord, AdsRecord, TrafficRecord, CombinedKPIs, FilterState, AggregatedData, LineGrowthMetric, ItemGrowthMetric, SeasonalityPoint, YearlySplitData, PivotRow, YearlyData, TimeSeriesData, ComparisonTimeSeriesPoint, ForecastRecord, MonthlyForecastPoint, ProductForecastData } from '../types';
import { SalesRecord, AdsRecord, TrafficRecord, CombinedKPIs, FilterState, AggregatedData, LineGrowthMetric, ItemGrowthMetric, SeasonalityPoint, YearlySplitData, PivotRow, YearlyData, TimeSeriesData, ComparisonTimeSeriesPoint, ForecastRecord, MonthlyForecastPoint, ProductForecastData, VendorCSVRow, VendorDailyRow } from '../types';
import * as XLSX from 'xlsx';
import Papa from 'papaparse';
/**
* Parses Vendor CSV and returns mapped VendorDailyRow items.
*/
export const processVendorCSV = (fileOrContent: File | string): Promise<VendorDailyRow[]> => {
return new Promise((resolve, reject) => {
const config = {
header: true,
skipEmptyLines: true,
complete: (results: any) => {
const rows = results.data
.filter((row: any) => row['Date'] && row['Market'] && row['ASIN'])
.map((row: any) => ({
date: row['Date'],
market: row['Market'],
asin: row['ASIN'],
product_title: row['Product Title'] || null,
tags: row['Tags'] || null,
bsr_top_rank: parseIntSafe(row['Top Level Category (Rank)']),
bsr_top_category: row['Top Level Category (Name)'] || null,
bsr_detail_rank: parseIntSafe(row['Detail Level Category (Rank)']),
bsr_detail_category: row['Detail Level Category (Name)'] || null,
avg_rating: parseCurrency(row['Average Rating']), // Uses existing parseCurrency which handles EU/US
num_reviews: parseIntSafe(row['Number of Reviews']),
buybox_owner: row['Buybox Seller Name'] || null,
buybox_price: parseCurrency(row['Buybox Price']),
amazon_has_buybox: row['Amazon Has Buybox'] === '1',
glance_views: parseIntSafe(row['Glance Views']),
}));
resolve(rows);
},
error: (error: any) => {
reject(error);
}
};
if (typeof fileOrContent === 'string') {
Papa.parse(fileOrContent, config);
} else {
Papa.parse(fileOrContent, config);
}
});
};
function parseIntSafe(val: string | undefined | null): number | null {
if (!val || typeof val !== 'string' || val.trim() === '') return null;
const cleaned = val.replace(/\./g, '').replace(',', '.').replace(/[^0-9.]/g, '');
const num = parseInt(cleaned, 10);
return isNaN(num) ? null : num;
}
// Helper to parse currency values handling both EU (1.234,56) and US/Standard (1,234.56 or 1234.56) formats
const parseCurrency = (value: string): number => {
if (!value) return 0;