Creating ISA and GSA segments

Hello all,

I have a flat file coming from my WMS that needs to be converted into an X12 E.D.I. file. The flat file doesn't contain the information needed for an ISA/GS segment so I'm attempting to build one. I know that much of the information can be hardcoded, but I wanted an outside opinion on whether I can use random number generation for the Interchange and Group Control numbers.

Would that work? Or is there a better way of creating these segments?

0

Comments

9 comments
Date Votes
  • Jack Harris random numbers will typically work unless the destination you are sending this to does validation on what numbers have previously been sent. If you need to increment each time, you would need to store the counter somewhere else. Here is an example of using our state api to store a counter. See example "Create a value to track a sequence number for an EDI data import (that would be updated every time the import is run)".

    0
  • How would I call that within the flow though?

    0
  • How would you make a random number handlebar? When I try the following I get letters:

    Expression:

    {{random "number" 9}}

    Result:

    0e85c472d

     

    0
  • Jack Harris for now, the "number" option in the random handlebar expression is only available for NetSuite exports/imports. Here is another way to come up with the same thing:

    {{substring (regexReplace (join "" (join "" (random "crypto" 32) (random "crypto" 32)) (random "crypto" 32)) "" "[^0-9]" "g") 0 9}}

    0
  • Jack Harris if you need to use the state api, here is an example of how I would use it via a preMap script. Notice that the output is the same data coming in, but it adds a new cache object. Within that, it has the stored control numbers for you to reference in your file definitions. Each time this runs, it will grab the stored control numbers and then increment the stored control values by 1. It's a bit complex, but should do the trick for you.

    
    
    import ioapi from 'integrator-api';
    
    //name your state key here
    var stateKey = 'edi840Increments';
    
    function preMap (options) {
      
      let stateCache;
      
      //get current cache key value, but if cache is not already made then create new cache
      try {
        stateCache = processCacheRequest(stateKey, options._integrationId, 'GET');
      } catch (e) {
        if (e.message.indexOf("Unable to locate cache with key") > -1) {
          stateCache = {
            interchangeControlNumber: '000000001',
            groupControlNumber: '000000001'
          };
          processCacheRequest(stateKey, options._integrationId, 'PUT', stateCache);
        } else {
          throw new Error(e.message);
        }
      }
      
      
      //now increment the control numbers by 1
      stateCache = {
        interchangeControlNumber: lpadIncrement(stateCache.interchangeControlNumber, "0", 9, 1),
        groupControlNumber: lpadIncrement(stateCache.groupControlNumber, "0", 9, 1)
      };
      processCacheRequest(stateKey, options._integrationId, 'PUT', stateCache, true);
      
      //console.log(JSON.stringify(processCacheRequest(stateKey, options._integrationId, 'GET')));
      
      return options.data.map((d) => {
        
        d.cache = stateCache;
        
        return {
          data: d
        }
      })
    }
    
    function processCacheRequest (cacheKey, integrationId, method, cacheUpdates, clearCacheFirst) {
    
      if(!cacheKey) throw new Error('Missing cacheKey parameter');
      if(!integrationId) throw new Error('Missing integrationId parameter');
    
      var cache = new StateCache({key: cacheKey, integrationId});
    
      if (method === 'GET') {
        return getCache(cache);
      } else if (method === 'PUT') {
        if (!clearCacheFirst) {
          clearCacheFirst = false;
        }
        return putCache(cache, cacheUpdates, clearCacheFirst);
      } else {
        throw new Error('method !== PUT or GET');
      }
    }
    
    function getCache(cache){
      return cache.read();
    }
    
    function putCache(cache, cacheUpdates, clearCacheFirst){
      if (!cacheUpdates) throw new Error('!cacheUpdates');
    
      if (clearCacheFirst) {
        cache.clear();
      }
    
      return cache.update({cacheUpdates: cacheUpdates});
    }
    
    class CacheMissingError extends Error {}
    
    class StateCache {
      constructor({key, integrationId}){
        this.key = key;
        this.integrationId = integrationId;
      }
    
      update({cacheUpdates}){
        const startingVal = this.read({ignoreMissing: true});
        const updatedCacheValue = {...startingVal, ...cacheUpdates};
    
        const updateCacheValueRes = ioapi.state.putForResource({
          resourceType: 'integrations',
          _id: this.integrationId,
          key: this.key,
          value: updatedCacheValue
        });
        //console.debug(JSON.stringify(updateCacheValueRes));
    
        return updatedCacheValue;
      }
    
      read({ignoreMissing} = {}){
        let getCacheValueRes;
        try {
          getCacheValueRes = ioapi.state.getForResource({
            resourceType: 'integrations',
            _id: this.integrationId,
            key: this.key
          });
        } catch(e) {
          if(ignoreMissing)
            getCacheValueRes = {};
          else
            throw new CacheMissingError(`Unable to locate cache with key: ${this.key}`);
        }
        //console.debug('getCacheValueRes', JSON.stringify(getCacheValueRes));
    
        return getCacheValueRes;
      }
    
      clear(){
        const deleteCacheValueRes = ioapi.state.deleteForResource({
          resourceType: 'integrations',
          _id: this.integrationId,
          key: this.key
        });
        //console.debug(JSON.stringify(deleteCacheValueRes));
      }
    
    }
    
    
    function lpadIncrement (string, padString, length, increment) {
      var str = (Number(string) + increment).toString();
      while (str.length < length)
          str = padString + str;
      return str;
    }
    2
  • Kit Hunter I think you asked about the same thing on office hours today. You could utilize the above.

    1
  • Tyler Lamparter feel free to delete this comment due to clutter, but I did want to make sure to thank you profusely for this. Script looks amazing!

    0
  • Tyler Lamparter - Could this be modified to start recounting per flow run. For example, if I have one flow run then it appropriately increment for that flow run, but if a new flow is kicked off it would reset?

    0

Please sign in to leave a comment.

 

Didn't find what you were looking for?

New post