/** * EDIFACT Parser for DELFOR D04A * Parses raw EDI string into structured JSON */ window.EDIBridge = window.EDIBridge || {}; class DelforParser { static parse(content) { // Defaults let separator = '+'; let subSeparator = ':'; let decimal = '.'; let release = '?'; let terminator = "'"; // Clean raw content let raw = content.replace(/\r\n/g, '').replace(/\n/g, '').trim(); // 1. Detect UNA if (raw.startsWith('UNA')) { subSeparator = raw[3]; separator = raw[4]; decimal = raw[5]; release = raw[6]; terminator = raw[8]; raw = raw.substring(9); } // 2. Split Segments (Simple approach usually sufficient for well-formed EDI) // Advanced approach: Character-by-character to handle release chars const segments = []; let currentSeg = ''; let escaped = false; for (let i = 0; i < raw.length; i++) { const char = raw[i]; if (escaped) { currentSeg += char; escaped = false; } else if (char === release) { escaped = true; } else if (char === terminator) { if (currentSeg.trim().length > 0) { segments.push(this.parseSegment(currentSeg, separator, subSeparator, release)); } currentSeg = ''; } else { currentSeg += char; } } // Add final segment if no terminator at end if (currentSeg.trim().length > 0) { segments.push(this.parseSegment(currentSeg, separator, subSeparator, release)); } return { meta: { separator, subSeparator, release, terminator }, segments: segments }; } static parseSegment(segStr, sep, subSep, release) { // Tokenize by separator const tokenized = this.tokenize(segStr, sep, release); const tag = tokenized.shift(); // First token is always Tag (e.g. UNH) const elements = tokenized.map(token => { // Check for sub-separator if (token.includes(subSep)) { // Determine if subSep is escaped? // tokenize logic handles simple split. // We should tokenize the token by subSep const components = this.tokenize(token, subSep, release); return components; } return token; }); return { tag, elements }; } // Helper: Split string by delimiter, respecting release char static tokenize(str, delim, release) { const tokens = []; let currentToken = ''; let escaped = false; for (let i = 0; i < str.length; i++) { const char = str[i]; if (escaped) { currentToken += char; escaped = false; } else if (char === release) { escaped = true; } else if (char === delim) { tokens.push(currentToken); currentToken = ''; } else { currentToken += char; } } tokens.push(currentToken); return tokens; } /** * Extracts a unique Customer/Sender ID for auto-detection */ static getCustomerId(content) { if (!content) return null; // Search for UNB sender const unbMatch = content.match(/UNB\s*[\+\:]([^\+']+)[\+\:]([^\+']+)/i); if (unbMatch) { let sender = unbMatch[2]; if (sender.includes(':')) sender = sender.split(':')[0]; const clean = sender.trim(); if (clean && !clean.startsWith('000000')) return clean; } // Fallback to NAD+BY const nadMatch = content.match(/NAD\+BY\+([^\+':]+)/i); if (nadMatch) { return nadMatch[1].trim(); } return null; } } window.EDIBridge.DelforParser = DelforParser;