172 lines
6.2 KiB
JavaScript
172 lines
6.2 KiB
JavaScript
/**
|
|
* INI-style Config Parser for NAD/Weight/Dimension lookup tables
|
|
* All section lookups are case-insensitive
|
|
*/
|
|
window.EDIBridge = window.EDIBridge || {};
|
|
|
|
class ConfigParser {
|
|
static parse(text) {
|
|
const config = {};
|
|
const sectionMap = {};
|
|
let currentSection = null;
|
|
|
|
const lines = text.split(/\r?\n/);
|
|
for (const line of lines) {
|
|
const trimmed = line.trim();
|
|
if (!trimmed || trimmed.startsWith(';')) continue;
|
|
|
|
const sectionMatch = trimmed.match(/^\[(.+)\]$/);
|
|
if (sectionMatch) {
|
|
currentSection = sectionMatch[1];
|
|
config[currentSection] = config[currentSection] || {};
|
|
sectionMap[currentSection.toUpperCase()] = currentSection;
|
|
continue;
|
|
}
|
|
|
|
if (currentSection) {
|
|
const eqIdx = trimmed.indexOf('=');
|
|
if (eqIdx > 0) {
|
|
const key = trimmed.substring(0, eqIdx).trim();
|
|
const value = trimmed.substring(eqIdx + 1).trim();
|
|
config[currentSection][key] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
config.__sectionMap__ = sectionMap;
|
|
return config;
|
|
}
|
|
|
|
/** Case-insensitive section lookup */
|
|
static getSection(config, name) {
|
|
if (config[name]) return config[name];
|
|
const map = config.__sectionMap__ || {};
|
|
const realName = map[name.toUpperCase()];
|
|
if (realName && config[realName]) return config[realName];
|
|
return null;
|
|
}
|
|
|
|
/** Ensure a section exists, create if missing */
|
|
static ensureSection(config, name) {
|
|
if (!config[name]) {
|
|
config[name] = {};
|
|
if (!config.__sectionMap__) config.__sectionMap__ = {};
|
|
config.__sectionMap__[name.toUpperCase()] = name;
|
|
}
|
|
return config[name];
|
|
}
|
|
|
|
/** Find value trying multiple ID variations */
|
|
static findInSection(config, sectionName, plantId) {
|
|
const section = this.getSection(config, sectionName);
|
|
if (!section) return '';
|
|
const ids = [
|
|
plantId,
|
|
plantId.replace(/^0+/, ''),
|
|
plantId.padStart(10, '0'),
|
|
plantId.padStart(9, '0'),
|
|
plantId.padStart(8, '0'),
|
|
plantId.padStart(7, '0')
|
|
];
|
|
for (const id of ids) {
|
|
if (section[id] !== undefined) return section[id];
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/** Look up NAD record */
|
|
static lookupNAD(config, qualifier, plantId) {
|
|
const q = qualifier.toUpperCase();
|
|
return {
|
|
id: this.findInSection(config, `NAD_${q}_PARTY`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Party`, plantId) || plantId,
|
|
qual: this.findInSection(config, `NAD_${q}_QUAL`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Qual`, plantId) || '92',
|
|
name: this.findInSection(config, `NAD_${q}_NAME`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Name`, plantId),
|
|
name2: this.findInSection(config, `NAD_${q}_NAME2`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Name2`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Name_2`, plantId),
|
|
street: this.findInSection(config, `NAD_${q}_STREET`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Street`, plantId),
|
|
city: this.findInSection(config, `NAD_${q}_CITY`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_City`, plantId),
|
|
zip: this.findInSection(config, `NAD_${q}_POSTCODE`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Postcode`, plantId),
|
|
country: this.findInSection(config, `NAD_${q}_COUNTRY`, plantId) ||
|
|
this.findInSection(config, `NAD_${q}_Country`, plantId)
|
|
};
|
|
}
|
|
|
|
static lookupPacWeight(config, packMatSupp) {
|
|
const section = this.getSection(config, 'PAC_WEIGHT');
|
|
if (!section) return 0;
|
|
const val = section[packMatSupp] || section[packMatSupp.replace(/^0+/, '')];
|
|
return val ? parseFloat(val) : 0;
|
|
}
|
|
|
|
static lookupPacDimension(config, packMatSupp, dim) {
|
|
// dim = 'LENGTH', 'WIDTH', 'HEIGHT'
|
|
const section = this.getSection(config, 'PAC_' + dim);
|
|
if (!section) return 0;
|
|
const val = section[packMatSupp] || section[packMatSupp.replace(/^0+/, '')];
|
|
return val ? parseFloat(val) : 0;
|
|
}
|
|
|
|
static lookupLinWeight(config, suppMat) {
|
|
const section = this.getSection(config, 'LIN_WEIGHT');
|
|
if (!section) return 0;
|
|
const val = section[suppMat] || section[suppMat.replace(/^0+/, '').replace(/ /g, '')];
|
|
return val ? parseFloat(val) : 0;
|
|
}
|
|
|
|
static lookupRffAnk(config, sellerId) {
|
|
const section = this.getSection(config, 'RFF_ANK_SE');
|
|
if (!section) return '';
|
|
const ids = [sellerId, sellerId.replace(/^0+/, ''), sellerId.padStart(10, '0')];
|
|
for (const id of ids) {
|
|
if (section[id]) return section[id];
|
|
}
|
|
return '';
|
|
}
|
|
|
|
static lookupGeneral(config, key, defaultValue = '') {
|
|
const section = this.getSection(config, 'GENERAL');
|
|
if (!section) return defaultValue;
|
|
return section[key] || defaultValue;
|
|
}
|
|
|
|
static lookupCustomerMode(config, customerId) {
|
|
const id = customerId.trim();
|
|
|
|
if (config) {
|
|
const section = this.getSection(config, 'CUSTOMER_MAPPING');
|
|
if (section) {
|
|
const mode = section[id] || section[id.replace(/^0+/, '')];
|
|
if (mode) return mode;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/** Serialize config object back to INI text */
|
|
static serialize(config) {
|
|
const lines = [];
|
|
const skipKeys = new Set(['__sectionMap__']);
|
|
|
|
for (const section of Object.keys(config)) {
|
|
if (skipKeys.has(section)) continue;
|
|
lines.push('');
|
|
lines.push('[' + section + ']');
|
|
const entries = config[section];
|
|
for (const [key, value] of Object.entries(entries)) {
|
|
lines.push(key + '=' + value);
|
|
}
|
|
}
|
|
return lines.join('\r\n');
|
|
}
|
|
}
|
|
|
|
window.EDIBridge.ConfigParser = ConfigParser;
|