function preMap(options) {
const result = options.data.map(function(record) {
const errors = [];
const formattedRecord = {};
// Existing mappings
formattedRecord.syntaxIdentifier = record[“SYNTAX IDENTIFIER”] && record[“SYNTAX IDENTIFIER”][“Syntax identifier”] ? record[“SYNTAX IDENTIFIER”][“Syntax identifier”] : null;
formattedRecord.syntaxVersionNumber = record[“SYNTAX IDENTIFIER”] && record[“SYNTAX IDENTIFIER”][“Syntax version number”] ? record[“SYNTAX IDENTIFIER”][“Syntax version number”] : null;
formattedRecord.sender = record[“INTERCHANGE SENDER”] && record[“INTERCHANGE SENDER”][“Sender identification”] ? record[“INTERCHANGE SENDER”][“Sender identification”] : null;
formattedRecord.recipient = record[“INTERCHANGE RECIPIENT”] && record[“INTERCHANGE RECIPIENT”][“Recipient identification”] ? record[“INTERCHANGE RECIPIENT”][“Recipient identification”] : null;
formattedRecord.orderNumber = record[“Document/message number”] || null;
formattedRecord.orderDate = formatDate(record[“DATE/TIME/PERIOD”] && record[“DATE/TIME/PERIOD”][“Date/time/period”] ? record[“DATE/TIME/PERIOD”][“Date/time/period”] : null);
// New mapping for date of preparation
formattedRecord.preparationDate = formatDatePrep(record[“DATE/TIME OF PREPARATION”] && record[“DATE/TIME OF PREPARATION”][“Date of preparation”] ? record[“DATE/TIME OF PREPARATION”][“Date of preparation”] : null);
formattedRecord.messageReferenceNumber = record[“Message reference number”] || null;
// Extract Instructions from FTX
formattedRecord.instructions = null; // Initialize as null
if (record[“Segment Group FTX”] && Array.isArray(record[“Segment Group FTX”])) {
const genEntry = record[“Segment Group FTX”].find(FTX => FTX[“Text subject code qualifier”] === “GEN”);
if (genEntry && genEntry[“TEXT literal”] && genEntry[“TEXT literal”][“Free text value(FTX040-010)”]) {
formattedRecord.instructions = genEntry[“TEXT literal”][“Free text value(FTX040-010)”].replace(“‘r”, “”).trim();
}
}
// Extract Memo from RFF
formattedRecord.memo = record[“REFERENCE”] && record[“REFERENCE”][“Reference number”] ? record[“REFERENCE”][“Reference number”].replace(“‘r”, “”) : null;
// Customer extraction
var customer = null;
if (record[“Segment Group 2”] && Array.isArray(record[“Segment Group 2”])) {
customer = record[“Segment Group 2”].find(function(party) {
return party[“Party qualifier”] === “BY”;
});
}
if (customer) {
formattedRecord.customerId = customer[“PARTY IDENTIFICATION DETAILS”] && customer[“PARTY IDENTIFICATION DETAILS”][“Party id. identification”] ? customer[“PARTY IDENTIFICATION DETAILS”][“Party id. identification”] : null;
formattedRecord.customerName = customer[“STREET”] && customer[“STREET”][“Street and number/p.o. box”] ? customer[“STREET”][“Street and number/p.o. box”] : null;
formattedRecord.customerContact = customer[“Contact identifier”] ? customer[“Contact identifier”].replace(“:”, “”).trim() : null;
formattedRecord.customerPhone = extractPhone(customer[“Segment Group 2”]);
formattedRecord.customerFax = extractFax(customer[“Segment Group 2”]);
formattedRecord.customerEmail = extractEmail(customer[“Segment Group 2”]);
} else {
errors.push({ code: ‘MISSING_CUSTOMER’, message: ‘Customer information is missing’, source: ‘preMap’ });
}
// Shipping information extraction
var shipping = null;
if (record[“Segment Group 2”] && Array.isArray(record[“Segment Group 2”])) {
shipping = record[“Segment Group 2”].find(function(party) {
return party[“Party qualifier”] === “ST”;
});
}
formattedRecord.shippingAddress = {
line1: shipping && shipping[“STREET”] && shipping[“STREET”][“Street and number/p.o. box”] ? shipping[“STREET”][“Street and number/p.o. box”] : null,
city: shipping && shipping[“City name”] ? shipping[“City name”] : null,
state: shipping && shipping[“Country sub-entity identification”] ? shipping[“Country sub-entity identification”] : null,
zip: shipping && shipping[“Postcode identification”] ? shipping[“Postcode identification”] : null,
country: shipping && shipping[“Country, coded”] ? shipping[“Country, coded”].replace(“‘r”, “”) : “AU”,
};
// Extracting method of transport
formattedRecord.methodOfTransport = record[“Transport charges method of payment”] || null;
// Item extraction
const items = [];
let totalNumberOfItems = 0;
let totalNumberOfLines = 0;
if (record[“Segment Group 25”] && Array.isArray(record[“Segment Group 25”])) {
record[“Segment Group 25”].forEach(function(line) {
const itemNumberData = line[“ITEM NUMBER IDENTIFICATION”];
if (itemNumberData) {
const itemNumber = itemNumberData[“Item number”];
const trimmedItemId = itemNumber && itemNumber.startsWith(“OX”) ? trimPrefix(itemNumber, “OXT”) : itemNumber;
// Check if the item is “FREIGHT”
if (itemNumber === “FREIGHT”) {
formattedRecord.shippingCost = parseFloat(line[“PRICE INFORMATION”] && line[“PRICE INFORMATION”][“Price”] ? line[“PRICE INFORMATION”][“Price”].replace(“‘r”, “”) : “0”) || 0;
return; // Skip adding this line as an item
}
const productCodes = line[“Segment Group 26”] || [];
const productCodesString = productCodes
.filter(product => product[“ITEM NUMBER IDENTIFICATION(PIA020)”] && product[“ITEM NUMBER IDENTIFICATION(PIA020)”][“Item number type, coded”] === “VP'”)
.map(product => product[“ITEM NUMBER IDENTIFICATION(PIA020)”][“Item number”])
.filter(Boolean)
.join(‘, ‘);
const lineItem = {
lineNumber: line[“Line item number”] || null,
itemId: trimmedItemId,
productCode: productCodesString,
itemType: itemNumberData[“Item number type, coded”] ? itemNumberData[“Item number type, coded”].replace(“‘r”, “”) : null,
quantity: parseFloat(line[“QUANTITY DETAILS”] && line[“QUANTITY DETAILS”][“Quantity”] ? line[“QUANTITY DETAILS”][“Quantity”] : “0”) || 0,
unitPrice: parseFloat(line[“PRICE INFORMATION”] && line[“PRICE INFORMATION”][“Price”] ? line[“PRICE INFORMATION”][“Price”].replace(“‘r”, “”) : “0”) || 0,
comment: line[“FREE TEXT”] || null,
unitOfMeasure: line[“QUANTITY DETAILS”] && line[“QUANTITY DETAILS”][“Measurement unit code”] ? line[“QUANTITY DETAILS”][“Measurement unit code”].replace(“‘r”, “”) : null,
shipDate: formatDate(line[“DATE/TIME/PERIOD”] && line[“DATE/TIME/PERIOD”][“Date/time/period”] ? line[“DATE/TIME/PERIOD”][“Date/time/period”] : null) || null,
};
totalNumberOfItems += lineItem.quantity;
totalNumberOfLines += 1;
items.push(lineItem);
} else {
errors.push({ code: ‘MISSING_ITEM_NUMBER’, message: `Item number identification is missing for line ${line[“Line item number”] || ‘unknown’}`, source: ‘preMap’ });
}
});
} else {
errors.push({ code: ‘MISSING_ITEMS’, message: ‘Items information is missing’, source: ‘preMap’ });
}
formattedRecord.items = items;
formattedRecord.totals = {
totalNumberOfItems: totalNumberOfItems.toString(),
totalNumberOfLines: totalNumberOfLines.toString()
};
if (record[“Monetary amount”] && record[“Monetary amount”].includes(“:”)) {
const monetaryAmountSplit = record[“Monetary amount”].split(“:”);
formattedRecord.totalAmount = parseFloat(monetaryAmountSplit[1].replace(“‘r”, “”)) || 0;
} else {
errors.push({ code: ‘MISSING_MONETARY_AMOUNT’, message: ‘Monetary amount is missing or malformed’, source: ‘preMap’ });
}
return { data: formattedRecord, errors: errors.length > 0 ? errors : undefined };
});
return result;
}
// Helper function to format date in NetSuite format (YYYY-MM-DD)
function formatDate(dateString) {
if (!dateString || dateString.length !== 8) return null;
const year = dateString.substring(0, 4);
const month = dateString.substring(4, 6);
const day = dateString.substring(6, 8);
return `${year}-${month}-${day}`;
}
function formatDatePrep(dateString) {
if (!dateString || dateString.length !== 6) return null;
const year = `20${dateString.substring(0, 2)}`;
const month = dateString.substring(2, 4);
const day = dateString.substring(4, 6);
return `${year}-${month}-${day}`;
}
// Helper function to extract phone number from contact data
function extractPhone(contacts) {
if (!contacts || !Array.isArray(contacts)) return null;
for (let i = 0; i < contacts.length; i++) {
const contact = contacts[i];
if (contact[“Communication channel qualifier”] && contact[“Communication channel qualifier”].includes(“:TE”)) {
return contact[“Communication channel qualifier”].split(“:”)[0].trim().replace(/’r/g, “”);
}
}
return null;
}
// Helper function to extract fax number from contact data
function extractFax(contacts) {
if (!contacts || !Array.isArray(contacts)) return null;
for (let i = 0; i < contacts.length; i++) {
const contact = contacts[i];
if (contact[“Communication channel qualifier”] && contact[“Communication channel qualifier”].includes(“:FX”)) {
return contact[“Communication channel qualifier”].split(“:”)[0].trim().replace(/’r/g, “”);
}
}
return null;
}
// Helper function to extract email from contact data
function extractEmail(contacts) {
if (!contacts || !Array.isArray(contacts)) return null;
for (let i = 0; i < contacts.length; i++) {
const contact = contacts[i];
if (contact[“Communication channel qualifier”] && contact[“Communication channel qualifier”].includes(“:EM”)) {
return contact[“Communication channel qualifier”].split(“:”)[0].trim().replace(/’r/g, “”);
}
}
return null;
}
// Helper function to trim the specified prefix from the item number
function trimPrefix(itemNumber, prefix) {
if (itemNumber.startsWith(prefix)) {
return itemNumber.slice(prefix.length); // Removes the specified prefix (e.g., ‘T’)
}
return itemNumber; // Return as is if no prefix
}