Extending Jint with functions

<< Click to Display Table of Contents >>

Navigation:  Workflow Designer > JavaScript with Jint >

Extending Jint with functions

Previous pageReturn to chapter overview

Show/Hide Hidden Text

Example for JavaScript with functions

 

To enrich Jint with additional functions, it is sufficient to simply copy them into the script window. The Jint interpreter reads the functions, and they can then be used.

 

For the following example, I use the JavaScript activity.

 

JavaScriptFunctionsSample_001

 

As you can see in the image and in the code block, the functions are listed first, and only at the end comes the actual function call.

 

hmtoggle_plus1Codeblock

// EDI Parser for JavaScript (Jint Compatible)

// No external libraries required

 

// EDI Document class

function EDIDocument() {

  this.documentId = "";

  this.companyCode = "";

  this.documentNumber = "";

  this.processingDate = null;

  this.header = null;

  this.transaction = null;

  this.lineItems = [];

  this.additionalSegments = [];

}

 

// SA1 - Header Information

function EDIHeader() {

  this.documentId = "";

  this.companyCode = "";

  this.plant = "";

  this.orderReference = "";

  this.vendorName = "";

  this.additionalCode = "";

  this.documentNumber = "";

  this.orderDate = null;

  this.processingTime = "";

}

 

// SA2 - Transaction Details

function EDITransaction() {

  this.documentNumber = "";

  this.startDate = null;

  this.endDate = null;

  this.deliveryDate = null;

  this.currency = "";

  this.taxCode = "";

  this.referenceCode = "";

  this.businessPartnerCodes = [];

  this.paymentTerms = "";

  this.paymentCode = "";

}

 

// SA5 - Line Item Details

function EDILineItem() {

  this.documentNumber = "";

  this.lineItemNumber = 0;

  this.position = 0;

  this.itemType = "";

  this.materialCode = "";

  this.materialDescription = "";

  this.quantity = 0;

  this.orderDate = null;

  this.plannedDeliveryDate = null;

  this.confirmedDeliveryDate = null;

  this.unit = "";

  this.unitPrice = 0;

  this.totalValue = 0;

  this.priceType = "";

  this.batchInfo = "";

  this.plant = "";

  this.internalItemCode = "";

  this.countryCodes = [];

 

  // Calculate total value

  this.calculateTotalValue = function() {

      this.totalValue = this.quantity * this.unitPrice;

      return this.totalValue;

   };

}

 

// Generic segment for SA4, SA6, SA8, SA11

function EDISegment() {

  this.segmentType = "";

  this.documentId = "";

  this.companyCode = "";

  this.documentNumber = "";

  this.additionalFields = [];

}

 

// Main parser class

function EDIParser() {

 

  // Parse main EDI data string

  this.parseEDIData = function(ediData) {

      var document = new EDIDocument();

      var lines = ediData.split(/\r?\n/);

     

      for (var i = 0; i < lines.length; i++) {

          var line = lines[i].trim();

          if (line === "") continue;

         

          var fields = line.split('|');

          var segmentType = fields[0];

         

          switch (segmentType) {

              case "SA1":

                   document.header = this.parseSA1(fields);

                   document.documentId = document.header.documentId;

                   document.companyCode = document.header.companyCode;

                   document.documentNumber = document.header.documentNumber;

                   document.processingDate = document.header.orderDate;

                  break;

                 

              case "SA2":

                   document.transaction = this.parseSA2(fields);

                  break;

                 

              case "SA5":

                   document.lineItems.push(this.parseSA5(fields));

                  break;

                 

              case "SA4":

              case "SA6":

              case "SA8":

              case "SA11":

                   document.additionalSegments.push(this.parseGenericSegment(fields, segmentType));

                  break;

           }

       }

     

      return document;

   };

 

  // Parse SA1 header segment

  this.parseSA1 = function(fields) {

      var header = new EDIHeader();

       header.documentId = this.getField(fields, 1);

       header.companyCode = this.getField(fields, 2);

       header.plant = this.getField(fields, 3);

       header.orderReference = this.getField(fields, 4);

       header.vendorName = this.getField(fields, 5);

       header.additionalCode = this.getField(fields, 6);

       header.documentNumber = this.getField(fields, 7);

       header.orderDate = this.parseDate(this.getField(fields, 8));

       header.processingTime = this.parseTime(this.getField(fields, 10));

     

      return header;

   };

 

  // Parse SA2 transaction segment

  this.parseSA2 = function(fields) {

      var transaction = new EDITransaction();

       transaction.documentNumber = this.getField(fields, 3);

       transaction.startDate = this.parseDate(this.getField(fields, 4));

       transaction.endDate = this.parseDate(this.getField(fields, 5));

       transaction.deliveryDate = this.parseDate(this.getField(fields, 6));

       transaction.currency = this.getField(fields, 21); // Position 22 in data

       transaction.taxCode = this.getField(fields, 18); // Position 19 in data

       transaction.referenceCode = this.getField(fields, 30); // Position 31 in data

       transaction.paymentTerms = this.getField(fields, 41); // PayTo field

       transaction.paymentCode = this.getField(fields, 45);

     

      // Extract business partner codes

      for (var i = 32; i < Math.min(fields.length - 1, 42); i++) {

          var field = this.getField(fields, i);

          if (field !== "" && field.indexOf("_END") === -1) {

               transaction.businessPartnerCodes.push(field);

           }

       }

     

      return transaction;

   };

 

  // Parse SA5 line item segment

  this.parseSA5 = function(fields) {

      var lineItem = new EDILineItem();

       lineItem.documentNumber = this.getField(fields, 3);

       lineItem.lineItemNumber = this.parseInt(this.getField(fields, 4));

       lineItem.position = this.parseInt(this.getField(fields, 5));

       lineItem.itemType = this.getField(fields, 7);

       lineItem.materialCode = this.getField(fields, 8).replace(/^\s+|\s+$/g, ''); // trim

       lineItem.materialDescription = this.getField(fields, 10);

       lineItem.quantity = this.parseDecimal(this.getField(fields, 11));

       lineItem.orderDate = this.parseDate(this.getField(fields, 12));

       lineItem.plannedDeliveryDate = this.parseDate(this.getField(fields, 13));

       lineItem.confirmedDeliveryDate = this.parseDate(this.getField(fields, 14));

       lineItem.unit = this.getField(fields, 15);

       lineItem.unitPrice = this.parseDecimal(this.getField(fields, 16));

       lineItem.priceType = this.getField(fields, 17);

       lineItem.batchInfo = this.getField(fields, 40);

       lineItem.plant = this.getField(fields, 51);

       lineItem.internalItemCode = this.getField(fields, 65);

     

      // Calculate total value

       lineItem.calculateTotalValue();

     

      // Extract country codes

      var countryCodes = [

          this.getField(fields, 78),

          this.getField(fields, 79),

          this.getField(fields, 81)

       ];

     

      for (var i = 0; i < countryCodes.length; i++) {

          var code = countryCodes[i];

          if (code !== "" && code.length === 2) {

               lineItem.countryCodes.push(code);

           }

       }

     

      return lineItem;

   };

 

  // Parse generic segments (SA4, SA6, SA8, SA11)

  this.parseGenericSegment = function(fields, segmentType) {

      var segment = new EDISegment();

       segment.segmentType = segmentType;

       segment.documentId = this.getField(fields, 1);

       segment.companyCode = this.getField(fields, 2);

       segment.documentNumber = this.getField(fields, 3);

     

      // Add any additional non-empty fields

      for (var i = 4; i < fields.length - 1; i++) {

          var field = this.getField(fields, i);

          if (field !== "" && field.indexOf("_END") === -1) {

               segment.additionalFields.push(field);

           }

       }

     

      return segment;

   };

 

  // Helper methods

  this.getField = function(fields, index) {

      return index < fields.length ? fields[index] : "";

   };

 

  this.parseDate = function(dateString) {

      if (!dateString || dateString.length !== 8) {

          return null;

       }

     

      var year = parseInt(dateString.substring(0, 4));

      var month = parseInt(dateString.substring(4, 6)) - 1; // Month is 0-based

      var day = parseInt(dateString.substring(6, 8));

     

      if (isNaN(year) || isNaN(month) || isNaN(day)) {

          return null;

       }

     

      return new Date(year, month, day);

   };

 

  this.parseTime = function(timeString) {

      if (!timeString || timeString.length < 3) {

          return "";

       }

     

      var timeValue = parseInt(timeString);

      if (isNaN(timeValue)) {

          return "";

       }

     

      var hours = Math.floor(timeValue / 100);

      var minutes = timeValue % 100;

     

      return hours.toString().padStart(2, '0') + ":" + minutes.toString().padStart(2, '0');

   };

 

  this.parseInt = function(value) {

      var result = parseInt(value);

      return isNaN(result) ? 0 : result;

   };

 

  this.parseDecimal = function(value) {

      var result = parseFloat(value);

      return isNaN(result) ? 0 : result;

   };

 

  // Convert to JSON string

  this.toJson = function(document) {

      return JSON.stringify(document, this.jsonReplacer, 2);

   };

 

  // Custom JSON replacer to handle dates properly

  this.jsonReplacer = function(key, value) {

      if (value instanceof Date) {

          return value.toISOString().split('T')[0]; // YYYY-MM-DD format

       }

      return value;

   };

}

 

// Polyfill for padStart if not available (for older JS engines)

if (!String.prototype.padStart) {

  String.prototype.padStart = function(targetLength, padString) {

       targetLength = targetLength >> 0;

       padString = String(typeof padString !== 'undefined' ? padString : ' ');

      if (this.length > targetLength) {

          return String(this);

       } else {

           targetLength = targetLength - this.length;

          if (targetLength > padString.length) {

               padString += padString.repeat(targetLength / padString.length);

           }

          return padString.slice(0, targetLength) + String(this);

       }

   };

}

 

// Usage example function

function parseEDIExample() {

  var ediData = "Some EDI Data";

 

  var parser = new EDIParser();

  var document = parser.parseEDIData(ediData);

  var json = parser.toJson(document);

 

  return json;

}

 

// Export for use in different environments

if (typeof module !== 'undefined' && module.exports) {

   module.exports = {

      EDIParser: EDIParser,

      EDIDocument: EDIDocument,

      EDIHeader: EDIHeader,

      EDITransaction: EDITransaction,

      EDILineItem: EDILineItem,

      EDISegment: EDISegment,

       parseEDIExample: parseEDIExample

   };

}

 

parseEDIExample();