web stats
Mirth Tools: User defined functions - Page 2 - Mirth Community

Go Back   Mirth Community > Mirth Connect > Support

Reply
 
Thread Tools Display Modes
  #11  
Old 04-19-2012, 06:50 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,117
narupley is on a distinguished road
Default

Quote:
UPDATE: I've created a public GitHub repository to track these example channels, code templates, scripts, or whatever else!

https://github.com/nextgenhealthcare/connect-examples

To start with I only added the ones I wrote, because I didn't want to presume and add code from others without their explicit permission. Pull requests welcome!
UPDATE 2-13-13: Made a change so that segName can be a regular expression

Okay, this one might be helpful to some people....

getSegmentsAfter: Returns an array of segments with the specified name that come after a given segment in the message.

Say you have multiple OBR groups in your message. Sometimes you want to do something with only the OBXs that come after that particular OBR, and not necessarily all of the OBXs in the entire message. The same goes for NTEs after an OBX, etc. Assuming that you're not using the strict HAPI parser (most of us don't), this might be fairly tricky to do.

The getSegmentsAfter function does it for you. Given the root node (root), the segment you want to start at (startSeg), and the name of the segments you want to get (segName), this function will return an array of those segments.

There are two other optional parameters:
  • consecutiveInd: If this is true, then the segments to be collected are expected to come directly after the starting segment. If any segment is encountered that doesn't have a name of segName, collection is immediately stopped. If this is false, then collection is stopped when another segment of the same name as startSeg is encountered. For example, say you have the following message:
    Code:
    MSH...
    PID...
    OBR...
    OBX...
    OBX...
    NTE...
    OBX...
    OBR...
    OBX...
    If startSeg is the first OBR, segName is "OBX", and consecutiveInd is true, then getSegmentsAfter will return the first two OBXs in the message, but not the third one. If consecutiveInd is false, then it will return the first three OBXs, but not the fourth one.

  • stopSegNames: This is an array of segment names that you want to act as an "emergency brake" to stop collection. If one of these segments is encountered, then iteration is stopped. This is useful when, for example, you have a message like this:
    Code:
    MSH...
    PID...
    OBR...
    OBX...
    NTE...
    OBX...
    SPM...
    OBX...
    In HL7Land, the OBR segment contains two groups, the observation group (consisting of the first two OBXs) and the specimen group (consisting of the SPM and the third OBX). In this case you don't want to get consecutive OBXs because there may be NTEs/ZDSs in between, but on the other hand you don't want to include the OBX that is part of the specimen group. So if "SPM" is included in stopSegNames, then all will be good.

Examples
  • Get all OBXs after the first OBR segment:
    Code:
    getSegmentsAfter(msg,msg.OBR[0],'OBX')
  • Get all consecutive NTEs after the first OBX segment:
    Code:
    getSegmentsAfter(msg,msg.OBX[0],'NTE',true)
  • Get all OBXs after the first OBR segment, but don't include any OBXs in the SPM or ZBP groups:
    Code:
    getSegmentsAfter(msg,msg.OBR[0],'OBX',false,['SPM','ZBP'])
  • Add a new NTE segment to the first OBR group (at the order level rather than the observation level):
    Code:
    var newNTE = <NTE/>;
    newNTE['NTE.3']['NTE.3.1'] = 'whatever';
    var nteGroup = getSegmentsAfter(msg,msg.OBR[0],'NTE',true);
    if (nteGroup.length > 0)
         msg.children()[nteGroup[nteGroup.length-1].childIndex()] += newNTE;
    else
         msg.OBR[0] += newNTE;
  • Reset all of the set IDs of the OBXs after every OBR in the message:
    Code:
    for each (obr in msg.OBR) {
         var obxGroup = getSegmentsAfter(msg,obr,'OBX',false,['SPM','ZBP']);
         for (var i = 0; i <= obxGroup.length-1; i++)
              msg.children()[obxGroup[i].childIndex()]['OBX.1']['OBX.1.1'] = (i+1);
    }
  • Get all Z-segments after each OBR segment:
    Code:
    for each (obr in msg.OBR) {
    	for each (zseg in getSegmentsAfter(msg,obr,/Z[A-Z\d]{2}/)) {
    		// Do something
    	}
    }

The code:

Code:
/*
	Author: Nick Rupley
	Date Modified: 2/13/2013
	getSegmentsAfter: Returns an array of segments with the specified name that come after a given segment in the message.

	Arguments
	---------
		Required
		--------
			root:			The root HL7Message node of the message, or the parent of the segment node.
			startSeg:		The segment AFTER which to start collecting segments.
			segName:		The name (String or RegExp) of the segments you want to collect.

		Optional
		--------
			consecutiveInd:	If true, indicates that the segments are expected to come directly after startSeg. 
					If false, segments are collected until another segment with the same name as startSeg is encountered.
					Defaults to false.
			stopSegNames:	An array of segment names that, when encountered, stop the collection of segments.
*/

function getSegmentsAfter(root, startSeg, segName, consecutiveInd, stopSegNames) {
	function test(str) {
		return segName instanceof RegExp ? segName.test(str) : segName === str;
	}

	// The index to start collection is the next one up from the starting segment
	var index = startSeg.childIndex()+1;
	// The return array
	var out = [];
	// Boolean placeholder to stop iteration
	var done = false;
	// Object that will contain all of the stopSegNames strings, bound to a truthy value (1)
	var stopNames = {};
	// Indicates whether we have any stop segments
	var stopNamesInd = false;
	// If stopSegNames is defined
	if (stopSegNames !== undefined && stopSegNames !== null) {
		// Set our indicator to true
		stopNamesInd = true;
		// Add each string in the array to our object
		for each (name in stopSegNames)
			stopNames[name] = 1;
	}

	// Iterate through each child in the root, starting at the segment after startSeg, and
	// ending at the final segment, or when the done flag is set to true.
	while (index < root.children().length() && !done) {
		// If a stop segment is encountered, stop iteration
		if (stopNamesInd && root.children()[index].name().toString() in stopNames)
			done = true;
		// If a segment with the same name as startSeg is encountered, stop iteration
		else if (root.children()[index].name().toString() == startSeg.name().toString() && !consecutiveInd)
			done = true;
		// If we're only collecting consecutive segments and we encounter a segment with a name other than segName, stop iteration
		else if (!test(root.children()[index].name().toString()) && consecutiveInd)
			done = true;
		// If all previous tests passed, and the current segment has a name of segName, then add it to our array
		else if (test(root.children()[index].name().toString()))
			out.push(root.children()[index]);
		// Increment our index counter
		index++;
	}

	// Return the output array
	return out;
}
Attached Files
File Type: xml getSegmentsAfter.xml (3.0 KB, 416 views)
File Type: xml getSegmentsAfter (new 2-13-13).xml (3.1 KB, 780 views)

Last edited by narupley; 06-08-2018 at 10:35 AM.
Reply With Quote
  #12  
Old 05-09-2012, 08:39 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,117
narupley is on a distinguished road
Default

NOTE: This code template is probably not necessary for 3.0 because we now have the ChannelUtil utility class, which has methods to deploy/undeploy/start/stop/etc. channels and connectors. However you can still use this to deploy channels on a different instance of Mirth Connect.

deployChannels: Deploys channels using an array of channel IDs and an optional client info object.

Rather self-explanatory; you just pass it an array or comma-separated string of channel IDs, and it will initiate a Client and deploy the specified channels. Client connection settings are hard-coded as defaults, but they can be overridden via the optional clientInfo argument.

The function returns an object containing a status String element, a message String element, and an overloaded toString method. The status will be "SUCCESS" if the client was able to successfully login, and at least one of the channel IDs refers to an enabled channel. Otherwise, the status is "FAILURE".

Here's the code (also attached as a code template):

Code:
/*
	Author: Nick Rupley
	Date Modified: 5/9/2012

	deployChannels
	--------------
		Deploys channels using an array of channel IDs and an optional client info object.

	Arguments
	---------
		Required
		--------
		channelIds: An array of channel IDs, or a string containing a comma-separated list of channel IDs.
		
		Optional
		--------
		clientInfo: An object containing zero or more of the following elements:
			URL: The Mirth Connect Administrator URL to connect to.
			user: Username to connect with.
			pass: Password to connect with.
			version: Version of Mirth Connect to bind to.
			timeout: HTTPS Connection timeout in milliseconds.

	Return Value
	------------
		Returns an object containing a status String element, a message String element, 
		and an overloaded toString method. The status will be "SUCCESS" if the client
		was able to successfully login, and at least one of the channel IDs refers to
		an enabled channel. Otherwise, the status is "FAILURE".
*/

function deployChannels(channelIds,clientInfo) {
	var crlf = '\x0D\x0A', tab = '     ';
	var status = {status:'FAILURE', message:''};
	status.toString = function() {return this.status + ':' + crlf + this.message;};

	try {
		if (!(channelIds instanceof Array)) {
			channelIds = channelIds.replace(/\s/g,'');
			if (channelIds.length > 0)
				channelIds = channelIds.split(',');
			else
				channelIds = [];
		}
		if (channelIds.length <= 0)
			throw('');
	}
	catch(e) {
		status.message = 'Invalid Channel ID List.';
		return status;
	}

	var info = {
		URL: 'https://localhost:8443',
		user: 'admin',
		pass: 'admin',
		version: '2.2.1.5861',
		timeout: 10000
	};
	if (clientInfo) {
		info.URL = clientInfo.URL || info.URL;
		info.user = clientInfo.user || info.user;
		info.pass = clientInfo.pass || info.pass;
		info.version = clientInfo.version || info.version;
		if ((clientInfo.timeout || clientInfo.timeout === 0) && clientInfo.timeout >= 0)	
			info.timeout = clientInfo.timeout;
	}

	try {
		var client = new com.mirth.connect.client.core.Client(info.URL,info.timeout);
		var loginStatus = client.login(info.user,info.pass,info.version);
		status.message += 'Login status: ' + loginStatus.getStatus() + crlf;

		if (!loginStatus.getStatus().toString().startsWith('FAIL')) {
			var list = new java.util.ArrayList();
			var channels = {}, failures = [];
			var successMessage = 'Channels successfully deployed:' + crlf;
			var failureMessage = 'Disabled channels not deployed:' + crlf;

			for each (channel in client.getChannel(null).toArray())
				channels[channel.getId()] = channel.isEnabled();
			for each (channelId in channelIds)
				if (channels[channelId]) {
					list.add(channelId);
					successMessage += tab + channelId + crlf;
				}
				else {
					failures.push(channelId);
					failureMessage += tab + channelId + crlf;
				}

			client.deployChannels(list);
			status.status = list.size() > 0 ? 'SUCCESS' : 'FAILURE';
			status.message += (list.size() > 0 ? successMessage : '') + (failures.length > 0 ? failureMessage : '');
		}
		else
			status.message += loginStatus.getMessage() + crlf;

		try {client.logout();} catch (e) {}
	}
	catch(e) {
		status.status = 'FAILURE';
		status.message += e.toString() + crlf;
	}

	return status;
}
And an example of its use (a channel that accepts a CSV string of channelIds as Delimited Text and outputs the result of deployChannels to the server log):

Code:
logger.info(deployChannels(messageObject.getRawData().split(',')).toString());
Attached Files
File Type: xml deployChannels.xml (3.8 KB, 150 views)

Last edited by narupley; 10-17-2013 at 07:54 AM.
Reply With Quote
  #13  
Old 05-16-2012, 03:20 AM
StefanScholte StefanScholte is offline
 
Join Date: May 2009
Location: Netherlands, Harderwijk
Posts: 321
StefanScholte is on a distinguished road
Default

I believe this will also be useful to others.

Date(Time) is always a pain in the **** especially with javascript.
So we ended up developing a javascript object that does the translation.
note the date is still string based note a javascript Date object.

You can set any date(time) you want and get any other format back.

Code:
/*
	Author(s): Stefan Scholte /Barry van der Veen
	Isala Klinieken Zwolle The Netherlands

	InternalDateTimeObject
	--------------
		Sets or gets Date(time) in numerous formats.

*/

function InternalDateTimeObject()
{
	this.innerDate = '';

	this.GetHL7UniversalDateTimeWithMilliseconds = function() 
	{
		return this.innerDate;
	}

	this.GetHL7UniversalDateTime = function() 
	{
		return this.GetDateFromCustomTemplate("yyyyMMddHHmmss");
	}

	this.GetHL7UniversalDate = function() 
	{
		return this.GetDateFromCustomTemplate("yyyyMMdd");
	}

	this.GetDBDateTimeEN = function() 
	{
		return this.GetDateFromCustomTemplate("yyyy-MM-dd HH:mm:ss");
	}

	this.GetDBDateEN = function() 
	{
		return this.GetDateFromCustomTemplate("yyyy-MM-dd");
	}

	this.GetDBDateTimeNL = function() 
	{
		return this.GetDateFromCustomTemplate("dd-MM-yyyy HH:mm:ss");
	}
	this.GetDBDateNL = function() 
	{
		return this.GetDateFromCustomTemplate("dd-MM-yyyy");
	}

	this.GetTime = function()
	{
		return this.GetDateFromCustomTemplate("HH:mm:ss");
	}

	this.GetTimeWithMilliseconds = function()
	{
		return this.GetDateFromCustomTemplate("HH:mm:ss.SSS");
	}
	this.GetWeek = function()
	{
		return this.GetDateFromCustomTemplate("ww");
	}

	this.SetCurrentDate = function()
	{
		this.innerDate = DateUtil.getCurrentDate('yyyyMMddHHmmssSSS');
	}

	this.SetFromDBDateNL = function(strDate)
	{
		this.innerDate = this.SetDateFromCustomTemplate("dd-MM-yyyy",strDate);
	}

	this.SetFromDBDateEN = function(strDate)
	{
		this.innerDate = this.SetDateFromCustomTemplate("yyyy-MM-dd",strDate);
	}

	this.SetFromDBDateTimeNL = function(strDate)
	{
		this.innerDate = this.SetDateFromCustomTemplate("dd-MM-yyyy HH:mm:ss",strDate);
	}

	this.SetFromDBDateTimeEN = function(strDate)
	{
		this.innerDate = this.SetDateFromCustomTemplate("yyyy-MM-dd HH:mm:ss",strDate);
	}


	this.SetFromHL7UniversalDate = function(strDate)
	{
		this.innerDate = this.SetDateFromCustomTemplate("yyyyMMdd",strDate);
	}

	this.SetFromHL7UniversalDateTime = function(strDate)
	{
		this.innerDate = this.SetDateFromCustomTemplate("yyyyMMddHHmmss",strDate);
	}


	this.GetDateFromCustomTemplate = function (pattern) 
	{
		if (this.innerDate == '')
			return this.innerDate;
		else
			return DateUtil.convertDate ("yyyyMMddHHmmssSSS", pattern, this.innerDate);
	}

	this.SetDateFromCustomTemplate = function (pattern, strDate) 
	{
		if(!strDate || strDate == '')
			return '';
		else
			return DateUtil.convertDate (pattern,"yyyyMMddHHmmssSSS", strDate);
	}
}

//Formatting options
// yyyy year (four-digit)
// M, MM month, month with leading 0
// d, dd day, day with leading 0
// HH hour, 24-hour-format
// hh hour, 12-hour-format
// mm minutes
// ss seconds
// SSS milliseconds
// ww week in year
usage:

Code:
//Make a new InternalDateTimeObject instance.
var date = new InternalDateTimeObject();

//You can set the currentdate in the object
date.SetCurrentDate();
//or set a specific date(time)
date.SetFromDBDateTimeEN("2012-04-30 12:58:57");

//And if you have special formatting you can use this option

date.SetDateFromCustomTemplate ("yyyy/dd/MM/", "2012/03/04") ;

//And this is how you can get the date(times) back.

var englishDateTime = date.GetDBDateTimeEN(); 
var HL7DateTime = date.GetHL7UniversalDateTimeWithMilliseconds();; 


//Here are all the getters
date.GetHL7UniversalDateTimeWithMilliseconds();; 
date.GetHL7UniversalDateTime(); 
date.GetHL7UniversalDate(); 
date.GetDBDateTimeEN(); 
date.GetDBDateEN(); 
date.GetDBDateTimeNL(); 
date.GetDBDateNL(); 
date.GetTime();
date.GetTimeWithMilliseconds();
date.GetWeek();




//And here are all the setters
date.SetCurrentDate();
date.SetFromDBDateNL("30-04-2012");
date.SetFromDBDateEN("2012-04-30");
date.SetFromDBDateTimeNL("30-04-2012 12:58:57");
date.SetFromDBDateTimeEN("2012-04-30 12:58:57");
date.SetFromHL7UniversalDate("20120430");
date.SetFromHL7UniversalDateTime(20120430125857)
date.GetDateFromCustomTemplate ("yyyy/dd/MM/"); 
date.SetDateFromCustomTemplate ("yyyy/dd/MM/", "2012/03/04") ;

Last edited by StefanScholte; 05-16-2012 at 03:34 AM.
Reply With Quote
  #14  
Old 05-17-2012, 05:07 AM
panickc panickc is offline
OBX.3 Kenobi
 
Join Date: Dec 2007
Posts: 127
panickc is an unknown quantity at this point
Default String Functions

Here's some string functions I use all the time, simple but effective. -cp

function startsWith(str, prefix) {
return str.indexOf(prefix) === 0;
}

function endsWith(str, suffix) {
return str.match(suffix+"$")==suffix;
}

function Left(str, n){
if (n <= 0)
return "";
else if (n > String(str).length)
return str;
else
return String(str).substring(0,n);
}
function Right(str, n){
if (n <= 0)
return "";
else if (n > String(str).length)
return str;
else {
var iLen = String(str).length;
return String(str).substring(iLen, iLen - n);
}
}
Reply With Quote
  #15  
Old 06-11-2012, 03:31 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,117
narupley is on a distinguished road
Default

Quote:
UPDATE: I've created a public GitHub repository to track these example channels, code templates, scripts, or whatever else!

https://github.com/nextgenhealthcare/connect-examples

To start with I only added the ones I wrote, because I didn't want to presume and add code from others without their explicit permission. Pull requests welcome!
renameField: Returns a copy of the given HL7 field, changing all segment names to the given name.

It has two parameters, the field node you want to change, and the new segment name to give the node (and all of it's descendants).

Examples:

Copy PID.2 over to PID.3 without having to map over each individual component/subcomponent:

Code:
msg.PID['PID.3'] = renameField(msg.PID['PID.2'],'PID.3');
The code:

Code:
/*
	Author: Nick Rupley
	Date Modified: 1/6/2012
*/

function renameField(oldField,name) {
	String.prototype.entityReplace = function() {return this.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/'/g,'&apos;').replace(/</g,'&lt;').replace(/>/g,'&gt;');};
	var out = new XML();
	for each (field in oldField) {
		var outField = new XML('<'+name+'/>');
		for each (component in field.children()) {
			var cname = name + component.name().toString().substring(component.name().toString().indexOf('.',component.name().toString().indexOf('.')+1));
			if (component.children().length() > 1) {
				// Has subcomponents
				var outComponent = new XML('<'+cname+'/>');
				for each (subcomponent in component.children()) {
					var scname = name + subcomponent.name().toString().substring(subcomponent.name().toString().indexOf('.',subcomponent.name().toString().indexOf('.')+1));
					var outSubcomponent = new XML('<'+scname+'>'+subcomponent.toString().entityReplace()+'</'+scname+'>');
					outComponent.scname = outSubcomponent;
				}
				outField.cname = outComponent;
			}
			else
				outField.cname = new XML('<'+cname+'>'+component.toString().entityReplace()+'</'+cname+'>');
		}
		out += outField;
	}
	return out;
}
Attached Files
File Type: xml renameField.xml (1.9 KB, 135 views)
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.

Last edited by narupley; 06-08-2018 at 10:35 AM.
Reply With Quote
  #16  
Old 07-26-2012, 08:08 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,117
narupley is on a distinguished road
Default createSegmentBefore, insertSegmentBefore, and insertSegmentAfter

Quote:
UPDATE: I've created a public GitHub repository to track these example channels, code templates, scripts, or whatever else!

https://github.com/nextgenhealthcare/connect-examples

To start with I only added the ones I wrote, because I didn't want to presume and add code from others without their explicit permission. Pull requests welcome!
This was suggested by someone in the IRC channel...

createSegmentBefore: Works similarly to createSegmentAfter; just creates a new segment with the given name and inserts it before the given segment.

insertSegmentBefore: Works like createSegmentBefore, except that you pass it the segment to insert, rather than having the function create a new segment.

insertSegmentAfter: Works like createSegmentAfter, except that you pass it the segment to insert, rather than having the function create a new segment.

Examples:

Create a new ORC segment before each OBR in the message and then modify it:

Code:
for each (obr in msg.OBR) {
	var orc = createSegmentBefore('ORC',obr);
	orc['ORC.1']['ORC.1.1'] = '1';
	// Etc.
}
Insert a pre-modified ORC segment before each OBR in the message:

Code:
for each (obr in msg.OBR) {
	var orc = <ORC/>;
	orc['ORC.1']['ORC.1.1'] = '1';
	// Etc.
	insertSegmentBefore(orc,obr);
}
Insert a pre-modified PV1 segment after the PID segment:

Code:
var pv1 = <PV1/>;
pv1['PV1.1']['PV1.1.1'] = '1';
// Etc.
insertSegmentAfter(pv1,msg.PID);
The code:

Code:
function createSegmentBefore(insertSegmentName, beforeThisSegment) {
	var msgObj = beforeThisSegment;
	while (msgObj.parent() != undefined) {
		msgObj = msgObj.parent();
	}
	msgObj.insertChildBefore(beforeThisSegment[0], new XML('<' + insertSegmentName + '></' + insertSegmentName + '>'));
	return msgObj.child(beforeThisSegment[0].childIndex() - 1);
}

function insertSegmentBefore(insertSegment, beforeThisSegment) {
	var msgObj = beforeThisSegment;
	while (msgObj.parent() != undefined) {
		msgObj = msgObj.parent();
	}
	msgObj.insertChildBefore(beforeThisSegment[0], insertSegment);
	return msgObj.child(beforeThisSegment[0].childIndex() - 1);
}

function insertSegmentAfter(insertSegment, afterThisSegment) {
	var msgObj = afterThisSegment;
	while (msgObj.parent() != undefined) {
		msgObj = msgObj.parent();
	}
	msgObj.insertChildAfter(afterThisSegment[0], insertSegment);
	return msgObj.child(afterThisSegment[0].childIndex() + 1);
}
Attached Files
File Type: xml SegmentCodeTemplates.xml (1.9 KB, 290 views)
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.

Last edited by narupley; 06-08-2018 at 10:35 AM.
Reply With Quote
  #17  
Old 07-30-2012, 09:54 AM
Bostad Bostad is offline
Level 85 Channel Wizard
 
Join Date: Mar 2009
Location: Stratford Ontario
Posts: 712
Bostad is an unknown quantity at this point
Smile Daily Scheduler

I've seen people ask for the ability to schedule a channel to only run on certain days of the week.

I've come up with a 2-part solution.

The first part:

In the deploy script of every channel you wish to schedule:
Code:
//This goes into the scheduled channels Deploy Script

//change the days you wish your channel to run into the next line using the first 2 letters of the each day separated by ~


var strSched = channelId + ',Mo~We~Fr';


var fname = channelId + '_sched.sch';

//in the line below you will need to change the 'folders/files/Channels/' to a folder reachable from your Mirth Server

FileUtil.write('/folders/files/Channels/' + fname, false, strSched);


//make sure the return; command is below this line!

return;
This will write a text file with the extension .sch in the folder you specify.

That file will be used by the attached channel which is set to run just after midnight.

If you need to run the controller channel at other times, simply "Deploy Channel".
Attached Files
File Type: xml Channel Scheduler.xml (11.5 KB, 249 views)
__________________
I can be reached through gmail and Google Talk using davidrothbauer at gmail dot com
http://www.linkedin.com/pub/david-rothbauer/5/923/518
codeismydrug.wordpress.com
hl7coders.wordpress.com

Test all my code suggestions prior to implementation
Reply With Quote
  #18  
Old 07-30-2012, 07:51 PM
ycyangcai ycyangcai is offline
Mirth Newb
 
Join Date: Mar 2011
Location: china
Posts: 10
ycyangcai is on a distinguished road
Default

that's nice!
Reply With Quote
  #19  
Old 09-06-2012, 03:36 PM
MikeCaldwell MikeCaldwell is offline
Where are the forums?
 
Join Date: Mar 2008
Location: Sacramento, CA
Posts: 154
MikeCaldwell
Default Keep it up

Man, I need to add some stuff, that's what I am talking about.. SHARING! Mirth and the WIKI LACK some serious hints/tips/help. If this gets buried in the WIKI could you please make sure the EXACT link is placed as the first item on on this thread so we dont spend days looking for it, it's nice having right here btw.
__________________
Mike Caldwell
Alliance HealthCare - GE VAR
Rocklin, CA
Centricity PM/EMR Support - Developer - Network Engineer
http://MirthPRO.Com
Reply With Quote
  #20  
Old 02-06-2013, 09:09 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,117
narupley is on a distinguished road
Default Replace in All Descendant XML Nodes

Quote:
UPDATE: I've created a public GitHub repository to track these example channels, code templates, scripts, or whatever else!

https://github.com/nextgenhealthcare/connect-examples

To start with I only added the ones I wrote, because I didn't want to presume and add code from others without their explicit permission. Pull requests welcome!
replaceAllInXML: Recursively iterates through all descendant nodes of an E4X XML object and makes a string replacement.

This is useful if you want to make a global replacement in your message but only want to do it for a specific connector. Obviously you can do this in a preprocessor, but if you only want it to happen for a single destination, this function will allow you do to that easily.

Parameters:
  • parent: The node to recursively iterate through.
  • regexp: The regular expression to test against at each leaf (text) node. This should be a RegExp object, like "new RegExp('foo','g')" or "/foo/g".
  • replacement: The string with which to replace.

Examples:
  • Replace all single quotes (') with two single quotes (''), e.g. to prepare for inserting into a database:
    Code:
    replaceAllInXML(msg,/'/g,"''");
  • If any dates occur in a PID or OBR segment that do not have the hour/minute/second defined (i.e. it's only yyyyMMdd, like "20130206"), then add on the HHmmss ("000000"). This might be used to send to a system that requires those date fields to be in the full yyyyMMddHHmmss format.
    Code:
    for each (seg in msg.*.(function(){return/PID|OBR/.test((new XML(this)).name())}()))
    	replaceAllInXML(seg,/(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])(?!\d)/g,'$&000000');

The code:

Code:
function replaceAllInXML(parent,regexp,replacement) {
	for each (child in parent.children())
		if (child.hasComplexContent())
			replaceAllInXML(child,regexp,replacement);
		else
			parent.children()[child.childIndex()] = child.toString().replace(regexp,replacement);
}
Attached Files
File Type: xml replaceAllInXML.xml (641 Bytes, 210 views)
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.

Last edited by narupley; 06-08-2018 at 10:35 AM.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 11:19 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Mirth Corporation