Erster Commit

This commit is contained in:
zed
2026-03-13 09:53:40 +01:00
commit 5ebcad02ed
3945 changed files with 974582 additions and 0 deletions

348
js/watcher-bridge.js Normal file
View File

@@ -0,0 +1,348 @@
/**
* Watcher Bridge Renderer-side logic for folder watcher
* Communicates with Electron main process via window.electronAPI
*
* Flow:
* 1. Main process detects new file via chokidar
* 2. Main sends file content to renderer via 'watcher-file-detected'
* 3. This bridge converts using the EDIBridge converters
* 4. Calls back to main to write output file
* 5. Calls back to main to move source file to archiv/
*/
window.EDIBridge = window.EDIBridge || {};
class WatcherBridge {
constructor() {
this.status = 'stopped'; // 'stopped', 'running', 'paused'
this.log = [];
this.maxLogEntries = 200;
this.onStatusChange = null;
this.onLogEntry = null;
this.config = null;
this._setupListeners();
}
_setupListeners() {
if (!window.electronAPI) return;
window.electronAPI.onFileDetected((data) => {
this._processDetectedFile(data);
});
window.electronAPI.onWatcherError((data) => {
this._addLog('error', data.filePath || '', data.error || 'Unbekannter Fehler');
});
window.electronAPI.onWatcherReady((data) => {
this._addLog('info', '', `Watcher bereit. Überwache: ${data.inputDir}`);
});
}
async _processDetectedFile(data) {
const { filePath, fileName, content, outputDir } = data;
this._addLog('info', fileName, 'Datei erkannt, starte Konvertierung...');
let konvertierungsmodus = 'Unbekannt';
let quellformat = null;
let zielformat = null;
let convertedContent = null;
let pError = null;
let outFileName = null;
try {
// Try to use a global config if this.config is not set (e.g. from app.js)
if (!this.config && window.app) {
this.config = window.app.config;
}
const result = this._convertContent(content, fileName);
if (result.error) {
this._addLog('error', fileName, result.error);
pError = result.error;
} else {
konvertierungsmodus = result.type;
quellformat = result.format === 'vda' ? 'EDIFACT DELFOR' : 'VDA 4913';
zielformat = result.targetFormat || (result.format === 'vda' ? 'VDA 4905' : (result.format === 'xml' ? 'IFM DELVRY03' : 'Bosch DESADV'));
convertedContent = result.output;
// Build output filename
const baseName = fileName.replace(/\.[^.]+$/, '');
const outExt = result.format === 'vda' ? '.vda' : (result.format === 'xml' ? '.xml' : '.edi');
outFileName = baseName + '_converted' + outExt;
const outPath = outputDir + '\\' + outFileName;
// Write converted file
const writeResult = await window.electronAPI.writeFile(outPath, result.output);
if (writeResult.error) {
this._addLog('error', fileName, `Schreibfehler: ${writeResult.error}`);
pError = writeResult.error;
} else {
this._addLog('success', fileName, `Konvertiert → ${outFileName} (${result.type})`);
// Move source file to archiv
const archiveResult = await window.electronAPI.moveToArchive(filePath);
if (archiveResult.error) {
this._addLog('error', fileName, `Archiv-Fehler: ${archiveResult.error}`);
} else {
this._addLog('info', fileName, 'Quelldatei nach archiv/ verschoben.');
}
}
}
} catch (e) {
this._addLog('error', fileName, `Fehler: ${e.message}`);
pError = e.message;
}
// Log to database
if (window.app && typeof window.app._logConversion === 'function') {
await window.app._logConversion({
dateiname: fileName,
ausgangsdateiname: outFileName,
quellformat: quellformat,
zielformat: zielformat,
konvertierungsmodus: konvertierungsmodus,
eingang_daten: content,
ausgang_daten: convertedContent,
status: pError ? 'FEHLERHAFT' : 'ERFOLGREICH',
fehlermeldung: pError,
quelle: 'WATCHER' // Auto tag
});
}
}
_convertContent(content, fileName) {
const trimmed = content.trim();
const upper = trimmed.toUpperCase();
// Detect file type and choose converter
if (upper.startsWith('UNA') || upper.startsWith('UNB')) {
// EDIFACT inbound → VDA 4905
return this._convertInbound(content, upper);
} else if (/^[0-9]{3}/.test(trimmed) || /^[57][0-9]{2}/.test(trimmed)) {
// VDA record (starts with 3-digit record type, e.g. 511, 711) → EDIFACT outbound
return this._convertOutbound(content);
} else {
return { error: `Dateiformat nicht erkannt (weder EDIFACT noch VDA). Erste Zeichen: "${trimmed.substring(0, 20)}..."` };
}
}
_convertInbound(content, upper) {
try {
const ConfigParser = window.EDIBridge.ConfigParser;
const DelforParser = window.EDIBridge.DelforParser;
let preferredMode = null;
if (ConfigParser && DelforParser) {
const customerId = DelforParser.getCustomerId(content);
console.log("Watcher detected Inbound Customer ID:", customerId);
if (customerId) {
preferredMode = ConfigParser.lookupCustomerMode(this.config, customerId);
console.log("Watcher mapped Inbound mode for ID", customerId, ":", preferredMode);
}
}
// 1. Prioritize mapped mode
if (preferredMode === 'inbound-ifm') {
const converter = window.EDIBridge.DelforToVDA4905Converter;
if (converter) {
const result = converter.convert(content);
return { output: result, type: 'IFM DELFOR → VDA 4905', format: 'vda' };
}
} else if (preferredMode === 'inbound-bosch') {
const parser = window.EDIBridge.DelforParser;
const generator = window.EDIBridge.VDA4905Generator;
if (parser && generator) {
const parsed = parser.parse(content);
const vda4905 = generator.generate(parsed);
return { output: vda4905, type: 'DELFOR → VDA 4905', format: 'vda' };
}
} else if (preferredMode === 'inbound-invrpt') {
const converter = window.EDIBridge.InvrptToVDA4913;
if (converter) {
const vda4913 = converter.convert(content);
return { output: vda4913, type: 'INVRPT → VDA 4913', format: 'vda' };
}
}
// 2. Fallback to hardcoded logic if no mapping
if (upper.includes('INVRPT')) {
const converter = window.EDIBridge.InvrptToVDA4913;
if (converter) {
const vda4913 = converter.convert(content);
return { output: vda4913, type: 'INVRPT → VDA 4913', format: 'vda' };
}
}
if (upper.includes('DELFOR') && upper.includes('D:04A')) {
const converter = window.EDIBridge.DelforToVDA4905Converter;
if (converter) {
const result = converter.convert(content);
return { output: result, type: 'IFM DELFOR D:04A → VDA 4905', format: 'vda' };
}
}
const parser = window.EDIBridge.DelforParser;
const generator = window.EDIBridge.VDA4905Generator;
if (parser && generator) {
const parsed = parser.parse(content);
const vda4905 = generator.generate(parsed);
return { output: vda4905, type: 'DELFOR → VDA 4905', format: 'vda' };
}
return { error: 'Passendes Inbound-Modul nicht geladen oder Typ unbekannt.' };
} catch (e) {
return { error: `Inbound-Konvertierung fehlgeschlagen: ${e.message}` };
}
}
_convertOutbound(content) {
try {
const VDAParser = window.EDIBridge.VDAParser;
if (!VDAParser) return { error: 'VDA Parser nicht geladen.' };
const vda = VDAParser.parse(content);
if (!vda.interchanges || vda.interchanges.length === 0) {
return { error: 'Keine gültigen VDA 4913 Daten gefunden.' };
}
// Check for customer mapping in config
const ConfigParser = window.EDIBridge.ConfigParser;
const customerId = VDAParser.getCustomerId(content);
console.log("Watcher detected Customer ID:", customerId);
let preferredMode = null;
if (ConfigParser && customerId) {
preferredMode = ConfigParser.lookupCustomerMode(this.config, customerId);
console.log("Watcher mapped mode for ID", customerId, ":", preferredMode);
}
if (preferredMode === 'outbound-ifm') {
const delvry = window.EDIBridge.VDA4913ToDELVRY03;
if (delvry) {
const idocs = delvry.convert(vda, this.config || {});
const output = delvry.toXML(idocs);
return { output, type: 'VDA 4913 → IFM DELVRY03', format: 'xml' };
}
} else if (preferredMode === 'outbound-zf') {
const desadvZf = window.EDIBridge.VDA4913ToDESADVZF;
if (desadvZf) {
const output = desadvZf.convert(content, {}, { linWeights: {}, pacWeights: {}, pacDims: {} }, this.config);
return { output, type: 'VDA 4913 → ZF DESADV', format: 'zf-edi', targetFormat: 'ZF DESADV' };
}
} else if (preferredMode === 'outbound-bosch') {
const desadv = window.EDIBridge.VDA4913ToDESADV;
if (desadv) {
const output = desadv.convert(content, {}, { linWeights: {}, pacWeights: {}, pacDims: {} }, this.config);
return { output, type: 'VDA 4913 → Bosch DESADV', format: 'edi' };
}
}
// Fallback to original logic if no mapping or mapped converter missing
// Try IFM DELVRY03 first
const delvry = window.EDIBridge.VDA4913ToDELVRY03;
if (delvry) {
const idocs = delvry.convert(vda, this.config || {});
const output = delvry.toXML(idocs);
return { output, type: 'VDA 4913 → IFM DELVRY03', format: 'xml' };
}
// Fallback to Bosch DESADV
const desadv = window.EDIBridge.VDA4913ToDESADV;
if (desadv) {
const output = desadv.convert(content, {}, { linWeights: {}, pacWeights: {}, pacDims: {} }, this.config);
return { output, type: 'VDA 4913 → Bosch DESADV', format: 'edi' };
}
return { error: 'Kein Outbound-Converter geladen.' };
} catch (e) {
return { error: `Outbound-Konvertierung fehlgeschlagen: ${e.message}` };
}
}
_addLog(level, fileName, message) {
const entry = {
time: new Date().toLocaleTimeString('de-DE'),
level,
fileName,
message
};
this.log.unshift(entry);
if (this.log.length > this.maxLogEntries) this.log.pop();
if (this.onLogEntry) this.onLogEntry(entry);
}
async start(inputDir, outputDir) {
if (!window.electronAPI) {
return { error: 'Electron API nicht verfügbar. App läuft im Browser-Modus.' };
}
const result = await window.electronAPI.startWatcher({ inputDir, outputDir });
if (result.success) {
this.status = 'running';
this._addLog('info', '', `Watcher gestartet. Überwache: ${inputDir}`);
if (this.onStatusChange) this.onStatusChange(this.status);
} else if (result.error) {
this._addLog('error', '', result.error);
}
return result;
}
async stop() {
if (!window.electronAPI) return;
const result = await window.electronAPI.stopWatcher();
if (result.success) {
this.status = 'stopped';
this._addLog('info', '', 'Watcher gestoppt.');
if (this.onStatusChange) this.onStatusChange(this.status);
}
return result;
}
async pause() {
if (!window.electronAPI) return;
const result = await window.electronAPI.pauseWatcher();
if (result.success) {
this.status = 'paused';
this._addLog('info', '', 'Watcher pausiert.');
if (this.onStatusChange) this.onStatusChange(this.status);
}
return result;
}
async resume() {
if (!window.electronAPI) return;
const result = await window.electronAPI.resumeWatcher();
if (result.success) {
this.status = 'running';
this._addLog('info', '', 'Watcher fortgesetzt.');
if (this.onStatusChange) this.onStatusChange(this.status);
} else if (result.error) {
this._addLog('error', '', result.error);
}
return result;
}
async loadSettings() {
if (!window.electronAPI) return { inputDir: '', outputDir: '', mode: 'auto' };
return await window.electronAPI.loadSettings();
}
async saveSettings(settings) {
if (!window.electronAPI) return;
return await window.electronAPI.saveSettings(settings);
}
async selectFolder() {
if (!window.electronAPI) return null;
return await window.electronAPI.selectFolder();
}
isElectron() {
return !!window.electronAPI;
}
}
window.EDIBridge.WatcherBridge = WatcherBridge;