mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 11:55:22 +02:00
feat(data): update sell-out parser mapping and validation for new structure
This commit is contained in:
@@ -270,8 +270,32 @@ const isAllowedCustomer = (customer: string): boolean => {
|
||||
|
||||
// --- SALES / SELL OUT MAPPING ---
|
||||
|
||||
export const validateSellOutHeaders = (headers: string[]) => {
|
||||
const normHeaders = headers.map(h => String(h).trim().toLowerCase());
|
||||
|
||||
const hasYear = normHeaders.includes('year');
|
||||
const hasTime = normHeaders.includes('month') || normHeaders.includes('week');
|
||||
const hasCustomerRef = normHeaders.includes('customer reference') || normHeaders.includes('asin');
|
||||
const hasEan = normHeaders.includes('ean');
|
||||
const hasUnits = normHeaders.includes('units');
|
||||
const hasAmount = normHeaders.includes('amount_eur') || normHeaders.includes('amount');
|
||||
|
||||
const missing = [];
|
||||
if (!hasYear) missing.push('YEAR');
|
||||
if (!hasTime) missing.push('MONTH or WEEK');
|
||||
if (!hasCustomerRef) missing.push('CUSTOMER REFERENCE');
|
||||
if (!hasEan) missing.push('EAN');
|
||||
if (!hasUnits) missing.push('UNITS');
|
||||
if (!hasAmount) missing.push('AMOUNT_EUR');
|
||||
|
||||
if (missing.length > 0) {
|
||||
throw new Error(`Invalid or missing critical columns in Sell-Out Report. Missing: ${missing.join(', ')}`);
|
||||
}
|
||||
};
|
||||
|
||||
const mapRowToRecord = (row: any, index: number): SalesRecord => {
|
||||
const customer = getColumnValue(row, ['NEW CUSTOMER', 'Customer', 'Client', 'Account', 'Partner', 'COUNTRY', 'Country', 'Market']) || 'Unknown';
|
||||
// Add exact matches to the front of getColumnValue arrays
|
||||
const customer = getColumnValue(row, ['NEW CUSTOMER', 'COUNTRY', 'Customer', 'Client', 'Account', 'Partner', 'Country', 'Market']) || 'Unknown';
|
||||
const yearStr = getColumnValue(row, ['YEAR', 'Year', 'D']);
|
||||
// Sanitize year string before parsing (remove commas/dots e.g. "2,023")
|
||||
let year = parseInt(yearStr.replace(/[,.]/g, '')) || 0;
|
||||
@@ -299,11 +323,11 @@ const mapRowToRecord = (row: any, index: number): SalesRecord => {
|
||||
]);
|
||||
|
||||
const sku = getColumnValue(row, ['RAW ARTICLE NO.', 'SKU', 'Sku', 'Item No']);
|
||||
const title = getColumnValue(row, ['ARTICLE NAME (Craze)', 'Title', 'TITLE', 'Product Title', 'Article Name', 'ArticleName']);
|
||||
const articleName = getColumnValue(row, ['ARTICLE NAME (Craze)', 'Article Name', 'ArticleName', 'Title']);
|
||||
const title = getColumnValue(row, ['ARTICLE NAME (Customer)', 'ARTICLE NAME (Craze)', 'Title', 'TITLE', 'Product Title', 'Article Name']);
|
||||
const articleName = getColumnValue(row, ['ARTICLE NAME (Craze)', 'ARTICLE NAME (Customer)', 'Article Name', 'ArticleName', 'Title']);
|
||||
|
||||
const unitsRaw = getColumnValue(row, ['UNITS', 'Units', 'Quantity', 'Qty']);
|
||||
const sellOutRaw = getColumnValue(row, ['AMOUNT', 'Sell Out', 'SellOut', 'Revenue', 'Sales', 'Turnover']);
|
||||
const sellOutRaw = getColumnValue(row, ['AMOUNT_EUR', 'AMOUNT', 'Sell Out', 'SellOut', 'Revenue', 'Sales', 'Turnover']);
|
||||
|
||||
return {
|
||||
id: `row-${index}`,
|
||||
@@ -329,6 +353,12 @@ export const processCSV = (fileOrContent: File | string): Promise<SalesRecord[]>
|
||||
skipEmptyLines: true,
|
||||
complete: (results: any) => {
|
||||
try {
|
||||
if (results.meta && results.meta.fields) {
|
||||
validateSellOutHeaders(results.meta.fields);
|
||||
} else if (results.data && results.data.length > 0) {
|
||||
validateSellOutHeaders(Object.keys(results.data[0]));
|
||||
}
|
||||
|
||||
const data: SalesRecord[] = results.data.map((row: any, index: number) => {
|
||||
return mapRowToRecord(row, index);
|
||||
})
|
||||
@@ -353,6 +383,10 @@ export const processExcel = async (file: File): Promise<SalesRecord[]> => {
|
||||
const worksheet = workbook.Sheets[firstSheetName];
|
||||
const jsonData = XLSX.utils.sheet_to_json(worksheet, { defval: "" });
|
||||
|
||||
if (jsonData.length > 0) {
|
||||
validateSellOutHeaders(Object.keys(jsonData[0] as object));
|
||||
}
|
||||
|
||||
const data: SalesRecord[] = jsonData.map((row: any, index: number) => {
|
||||
return mapRowToRecord(row, index);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user