This commit is contained in:
seb
2026-10-19 04:05:07 +02:00
parent 6fbdeaa070
commit 3450552f7c
3 changed files with 87 additions and 8 deletions

View File

@@ -506,11 +506,23 @@ export async function executeCompanyExport({
log.warn('Could not prefetch payment/shipping types:', err.message); log.warn('Could not prefetch payment/shipping types:', err.message);
} }
const entityMap = new Map();
try {
const entities = await store.entity.list(googleAuthId);
for (const ent of entities) {
entityMap.set(ent.id, ent);
}
} catch (err) {
log.warn('Could not prefetch entities for order export:', err.message);
}
const manifestCsvHeaders = [ const manifestCsvHeaders = [
'"id"', '"id"',
'"nr"', '"nr"',
'"extnr"', '"extnr"',
'"created_at"', '"created_at"',
'"customerNr"',
'"customerName"',
'"paymentType"', '"paymentType"',
'"shippingType"', '"shippingType"',
'"payed"', '"payed"',
@@ -543,11 +555,21 @@ export async function executeCompanyExport({
const payType = paymentMap.get(ord.id) || ord.payment?.type || ord.payments?.[0]?.type || 'Bar'; const payType = paymentMap.get(ord.id) || ord.payment?.type || ord.payments?.[0]?.type || 'Bar';
const shipType = shippingMap.get(ord.id) || ord.shipping?.type || ord.shippings?.[0]?.type || 'Selbstabholer'; const shipType = shippingMap.get(ord.id) || ord.shipping?.type || ord.shippings?.[0]?.type || 'Selbstabholer';
const entity = ord.entity || (ord.entityId ? entityMap.get(ord.entityId) : null);
const customerNr = ord.customerNr || entity?.number || ord.customer?.number || '';
const customerName = ord.customerName
|| entity?.name
|| [entity?.firstName, entity?.lastName].filter(Boolean).join(' ')
|| [ord.customerFirstName, ord.customerLastName].filter(Boolean).join(' ')
|| '';
manifestCsvRows.push([ manifestCsvRows.push([
formatCsvField(ord.id), formatCsvField(ord.id),
formatCsvField(ord.number), formatCsvField(ord.number),
formatCsvField(ord.externalNumber || ''), formatCsvField(ord.externalNumber || ''),
formatCsvField(ord.createdAt || ord.date || new Date().toISOString()), formatCsvField(ord.createdAt || ord.date || new Date().toISOString()),
formatCsvField(customerNr),
formatCsvField(customerName),
formatCsvField(payType), formatCsvField(payType),
formatCsvField(shipType), formatCsvField(shipType),
formatCsvField(ord.isPaid || ord.paid ? '1' : '0'), formatCsvField(ord.isPaid || ord.paid ? '1' : '0'),

View File

@@ -216,6 +216,7 @@ export async function executeCompanyImport({
ordersSkipped: ordersResult.ordersSkipped, ordersSkipped: ordersResult.ordersSkipped,
paymentsImported: ordersResult.paymentsImported, paymentsImported: ordersResult.paymentsImported,
shippingsImported: ordersResult.shippingsImported, shippingsImported: ordersResult.shippingsImported,
customersImported: ordersResult.customersImported || 0,
}, },
}; };
} }

View File

@@ -61,8 +61,11 @@ export async function importOrders({
let defaultCustomerGroupId = null; let defaultCustomerGroupId = null;
try { try {
const groups = await store.customergroup.list(googleAuthId); const groups = await store.customergroup.list(googleAuthId);
defaultCustomerGroupId = groups[0]?.id || null; const posGroup = groups.find((g) => g.name === 'POS' || g.name?.toUpperCase() === 'POS');
} catch {} defaultCustomerGroupId = posGroup?.id || groups[0]?.id || null;
} catch (err) {
log.warn('Could not list customer groups:', err.message);
}
let defaultWarehouseId = null; let defaultWarehouseId = null;
try { try {
@@ -77,31 +80,82 @@ export async function importOrders({
log.warn('Could not ensure warehouse:', err.message); log.warn('Could not ensure warehouse:', err.message);
} }
let customersImported = 0;
const entityMap = new Map(); const entityMap = new Map();
const entityByNumber = new Map();
try { try {
const entities = await store.entity.list(googleAuthId); const entities = await store.entity.list(googleAuthId);
for (const ent of entities) { for (const ent of entities) {
if (ent.name) { if (ent.name) {
entityMap.set(ent.name.trim().toLowerCase(), ent.id); entityMap.set(ent.name.trim().toLowerCase(), ent.id);
} }
if (ent.number) {
entityByNumber.set(String(ent.number).trim().toLowerCase(), ent.id);
}
} }
} catch {} } catch (err) {
log.warn('Could not list existing entities:', err.message);
}
const resolveEntityId = async (name, firstName) => { const resolveEntityId = async (name, firstName, number) => {
const cleanName = (name || '').trim(); const cleanName = (name || '').trim();
const cleanNr = (number || '').trim();
if (!cleanName || !defaultCustomerGroupId) return null; if (!cleanName || !defaultCustomerGroupId) return null;
const nrKey = cleanNr ? cleanNr.toLowerCase() : null;
if (nrKey && entityByNumber.has(nrKey)) {
return entityByNumber.get(nrKey);
}
const key = cleanName.toLowerCase(); const key = cleanName.toLowerCase();
if (entityMap.has(key)) return entityMap.get(key); if (!nrKey && entityMap.has(key)) return entityMap.get(key);
try { try {
const ent = await store.entity.create(googleAuthId, { const ent = await store.entity.create(googleAuthId, {
customergroupId: defaultCustomerGroupId, customergroupId: defaultCustomerGroupId,
name: cleanName, name: cleanName,
firstName: (firstName || '').trim() || undefined, firstName: (firstName || '').trim() || undefined,
number: cleanNr || undefined,
}); });
entityMap.set(key, ent.id); entityMap.set(key, ent.id);
if (ent.number) {
entityByNumber.set(String(ent.number).trim().toLowerCase(), ent.id);
}
if (nrKey) {
entityByNumber.set(nrKey, ent.id);
}
customersImported++;
return ent.id; return ent.id;
} catch (err) { } catch (err) {
if (cleanNr && err.message?.includes('Number already in use')) {
try {
const refreshed = await store.entity.list(googleAuthId).catch(() => []);
const found = refreshed.find(
(e) => String(e.number).trim().toLowerCase() === nrKey
);
if (found) {
entityByNumber.set(nrKey, found.id);
if (found.name) entityMap.set(found.name.trim().toLowerCase(), found.id);
return found.id;
}
} catch {}
try {
const ent = await store.entity.create(googleAuthId, {
customergroupId: defaultCustomerGroupId,
name: cleanName,
firstName: (firstName || '').trim() || undefined,
});
entityMap.set(key, ent.id);
if (ent.number) {
entityByNumber.set(String(ent.number).trim().toLowerCase(), ent.id);
}
customersImported++;
return ent.id;
} catch (retryErr) {
log.warn(`Could not create entity "${cleanName}":`, retryErr.message);
return null;
}
}
log.warn(`Could not create entity "${cleanName}":`, err.message); log.warn(`Could not create entity "${cleanName}":`, err.message);
return null; return null;
} }
@@ -218,9 +272,10 @@ export async function importOrders({
}; };
}); });
const custName = cleanValue(m.name ?? m.cName) || 'Laufkunde'; const custName = cleanValue(m.customerName ?? m.name ?? m.cName) || 'Laufkunde';
const custFirstName = cleanValue(m.firstName ?? m.cVorname); const custFirstName = cleanValue(m.firstName ?? m.cVorname);
const entityId = await resolveEntityId(custName, custFirstName); const custNr = cleanValue(m.customerNr ?? m.cKundenNr);
const entityId = await resolveEntityId(custName, custFirstName, custNr);
const dateStr = cleanValue(m.created_at ?? m.dErstellt); const dateStr = cleanValue(m.created_at ?? m.dErstellt);
const parsedDate = dateStr ? new Date(dateStr) : new Date(); const parsedDate = dateStr ? new Date(dateStr) : new Date();
@@ -380,13 +435,14 @@ export async function importOrders({
} }
progressTracker.emitProgress(true); progressTracker.emitProgress(true);
log.info(`Orders complete: ${ordersImported} created, ${ordersSkipped} skipped, ${paymentsImported} payments, ${shippingsImported} shippings`); log.info(`Orders complete: ${ordersImported} created, ${ordersSkipped} skipped, ${paymentsImported} payments, ${shippingsImported} shippings, ${customersImported} customers`);
return { return {
ordersImported, ordersImported,
ordersSkipped, ordersSkipped,
paymentsImported, paymentsImported,
shippingsImported, shippingsImported,
customersImported,
}; };
} }