PreMap hook to convert EDI JSON to objects in order to map

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

}

Leave a comment

Your email address will not be published. Required fields are marked *