fix: commit all BC sync files missing from repo

This commit is contained in:
Christian Vidal Wolf
2026-05-15 11:00:21 +02:00
parent 85794b4b52
commit 143f655f3c
14 changed files with 1701 additions and 49 deletions
+142
View File
@@ -0,0 +1,142 @@
import { ExcelRow } from '../types';
export interface MappingFieldPreview {
sourceLabel: string;
sourceIndex: number | null;
targetField: string;
value: any;
}
export interface BusinessCentralMappingPreview {
articleNo: string;
itemsPayload: Record<string, any>;
itemUnitsOfMeasurePayload: Record<string, any>;
itemsFields: MappingFieldPreview[];
itemUnitsFields: MappingFieldPreview[];
}
function findHeaderIndex(headers: string[], patterns: string[]): number {
const normalized = headers.map(h => String(h || '').toLowerCase());
return normalized.findIndex(header =>
patterns.every(pattern => header.includes(pattern.toLowerCase()))
);
}
function formatDateForBc(value: any): string | null {
if (value === null || value === undefined || value === '') return null;
if (typeof value === 'number' && value >= 25569 && value <= 60000) {
const excelEpoch = new Date(1899, 11, 30);
const date = new Date(excelEpoch.getTime() + value * 86400000);
return date.toISOString().split('T')[0];
}
const str = String(value).trim();
if (!str) return null;
if (/^\d{4}-\d{2}-\d{2}$/.test(str)) return str;
const parsed = new Date(str);
if (!Number.isNaN(parsed.getTime())) {
return parsed.toISOString().split('T')[0];
}
return str;
}
function getValue(row: ExcelRow, index: number | null): any {
if (index === null || index < 0) return null;
const value = row[index];
return value === undefined || value === '' ? null : value;
}
function toBcDecimal(value: any): number | null {
if (value === null || value === undefined || value === '') return null;
if (typeof value === 'number' && Number.isFinite(value)) return value;
const normalized = String(value).trim().replace(/\s+/g, '').replace(',', '.');
if (!normalized) return null;
const parsed = Number(normalized);
return Number.isFinite(parsed) ? parsed : null;
}
function makeFieldPreview(
sourceLabel: string,
sourceIndex: number | null,
targetField: string,
value: any
): MappingFieldPreview {
return { sourceLabel, sourceIndex, targetField, value };
}
export function buildBusinessCentralMappingPreview(headers: string[], row: ExcelRow): BusinessCentralMappingPreview {
const articleNoIdx = findHeaderIndex(headers, ['article', 'no']);
const articleDetailsEnIdx = findHeaderIndex(headers, ['article', 'details', 'english']);
const articleDetailsDeIdx = findHeaderIndex(headers, ['article', 'details', 'german']);
const launchDateIdx = findHeaderIndex(headers, ['launch']);
const readyToOrderDateIdx = findHeaderIndex(headers, ['ready']);
const moqIdx = findHeaderIndex(headers, ['moq']);
const shortDeIdx = findHeaderIndex(headers, ['short', 'description', 'german']);
const shortEnIdx = findHeaderIndex(headers, ['short', 'description', 'english']);
const cpnpIdx = findHeaderIndex(headers, ['cpnp']);
const unitsOuterIdx = findHeaderIndex(headers, ['units', 'outer']);
const innerWIdx = findHeaderIndex(headers, ['inner', 'w']);
const innerLIdx = findHeaderIndex(headers, ['inner', 'l']);
const innerHIdx = findHeaderIndex(headers, ['inner', 'h']);
const outerWIdx = findHeaderIndex(headers, ['outer', 'w']);
const outerLIdx = findHeaderIndex(headers, ['outer', 'l']);
const outerHIdx = findHeaderIndex(headers, ['outer', 'h']);
const articleNo = String(getValue(row, articleNoIdx) ?? '');
const itemsPayload = {
no: getValue(row, articleNoIdx),
articleDetailsEnglish: getValue(row, articleDetailsEnIdx),
articleDetailsGerman: getValue(row, articleDetailsDeIdx),
launchDate: formatDateForBc(getValue(row, launchDateIdx)),
readyToOrderDate: formatDateForBc(getValue(row, readyToOrderDateIdx)),
minimumOrderQuantity: toBcDecimal(getValue(row, moqIdx)),
shortDescriptionInGerman: getValue(row, shortDeIdx),
shortDescriptionInEnglish: getValue(row, shortEnIdx),
cpnpNo: getValue(row, cpnpIdx),
};
const itemUnitsOfMeasurePayload = {
itemNo: getValue(row, articleNoIdx),
qtyPerUnitOfMeasure6: toBcDecimal(getValue(row, unitsOuterIdx)),
width4: toBcDecimal(getValue(row, innerWIdx)),
length4: toBcDecimal(getValue(row, innerLIdx)),
height4: toBcDecimal(getValue(row, innerHIdx)),
width6: toBcDecimal(getValue(row, outerWIdx)),
length6: toBcDecimal(getValue(row, outerLIdx)),
height6: toBcDecimal(getValue(row, outerHIdx)),
};
return {
articleNo,
itemsPayload,
itemUnitsOfMeasurePayload,
itemsFields: [
makeFieldPreview('Article No.', articleNoIdx, 'no', itemsPayload.no),
makeFieldPreview('Article Details - English', articleDetailsEnIdx, 'articleDetailsEnglish', itemsPayload.articleDetailsEnglish),
makeFieldPreview('Article Details - German', articleDetailsDeIdx, 'articleDetailsGerman', itemsPayload.articleDetailsGerman),
makeFieldPreview('Launch Date', launchDateIdx, 'launchDate', itemsPayload.launchDate),
makeFieldPreview('Ready to Order Date', readyToOrderDateIdx, 'readyToOrderDate', itemsPayload.readyToOrderDate),
makeFieldPreview('MOQ', moqIdx, 'minimumOrderQuantity', itemsPayload.minimumOrderQuantity),
makeFieldPreview('Short Description - German', shortDeIdx, 'shortDescriptionInGerman', itemsPayload.shortDescriptionInGerman),
makeFieldPreview('Short Description - English', shortEnIdx, 'shortDescriptionInEnglish', itemsPayload.shortDescriptionInEnglish),
makeFieldPreview('CPNP', cpnpIdx, 'cpnpNo', itemsPayload.cpnpNo),
],
itemUnitsFields: [
makeFieldPreview('Article No.', articleNoIdx, 'itemNo', itemUnitsOfMeasurePayload.itemNo),
makeFieldPreview('Units Outer', unitsOuterIdx, 'qtyPerUnitOfMeasure6', itemUnitsOfMeasurePayload.qtyPerUnitOfMeasure6),
makeFieldPreview('CDU/Inner W (cm)', innerWIdx, 'width4', itemUnitsOfMeasurePayload.width4),
makeFieldPreview('CDU/Inner L (cm)', innerLIdx, 'length4', itemUnitsOfMeasurePayload.length4),
makeFieldPreview('CDU/Inner H (cm)', innerHIdx, 'height4', itemUnitsOfMeasurePayload.height4),
makeFieldPreview('Outer W (cm)', outerWIdx, 'width6', itemUnitsOfMeasurePayload.width6),
makeFieldPreview('Outer L (cm)', outerLIdx, 'length6', itemUnitsOfMeasurePayload.length6),
makeFieldPreview('Outer H (cm)', outerHIdx, 'height6', itemUnitsOfMeasurePayload.height6),
],
};
}