Erster Commit
This commit is contained in:
131
js/delfor-parser.js
Normal file
131
js/delfor-parser.js
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* 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;
|
||||
Reference in New Issue
Block a user