Write to Log File – Snippet for Smart Office Scripting

The following code can be used as a Snippet within the Lawson Smart Office Scripting Tool to output values to the Smart Office log file.

1
2
3
4
5
6
7
8
9
10
11
12
            /**
             * Write to LSO Log File
             * import Mango;
             * import log4net;
            */
            debug.WriteLine(Mango.Core.Storage.FileStorageMachineOnly.Current.FullFilePath("LawsonClient.log")); // filename + path
            var log: log4net.ILog = Mango.Core.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            if (log.IsInfoEnabled) log.Info("Hello World!");
            if (log.IsDebugEnabled) log.Debug("This is a Debug");
            if (log.IsErrorEnabled) log.Error("This is an Error");
            if (log.IsFatalEnabled) log.Fatal("This is Fatal");
            if (log.IsWarnEnabled) log.Warn("This is a Warning");
			/**
			 * Write to LSO Log File
		 	 * import Mango;
			 * import log4net;
			*/
            debug.WriteLine(Mango.Core.Storage.FileStorageMachineOnly.Current.FullFilePath("LawsonClient.log")); // filename + path
            var log: log4net.ILog = Mango.Core.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            if (log.IsInfoEnabled) log.Info("Hello World!");
            if (log.IsDebugEnabled) log.Debug("This is a Debug");
            if (log.IsErrorEnabled) log.Error("This is an Error");
            if (log.IsFatalEnabled) log.Fatal("This is Fatal");
            if (log.IsWarnEnabled) log.Warn("This is a Warning");

Copy the code and save as WriteLogFile.jss, for example, or copy directly into the Script tool and Save Selection as Snippet.

AP10 Verify Unique Tax ID – Smart Office Scripting

When entering a new vendor a button is provided to query the system to determine if the tax-id entered is unique, if not unique the vendor(s) with the matching tax-id id are displayed.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
//-----------------------------------------------------------------------------
//  JScript Example
//  Created by:     Josh Geving - Solutions Group
//
//  Description:    When entering a new vendor a button is provided to
//                  query the system to determine if the tax-id entered
//                  is unique, if not unique the vendor(s) with the matching
//                  tax-id id are displayed
//
//  Last Tested on Smart Office Version 10.0.1.5
//-----------------------------------------------------------------------------
 
import System;
import System.Windows;
import System.Windows.Controls;
import S3.Client.Forms;
import System.Collections;
import System.Collections.Generic;
import System.Windows.Data;
import Mango.UI;
import Mango.UI.Core;
import Mango.UI.Services;
 
package S3.Client.Forms.JScript {
 
class JjgAP10CheckTaxID
{
    var console, form, formGrid, button;
 
    public function Init(element: Object, args: Object, controller : Object, debug : Object)
    {
        try {
            form = controller;
            formGrid = form.FormGrid;
            console = debug;
 
            console.WriteLine("Script initializing...");
            if (element != null)
                console.WriteLine("Connected element: " + element.Name);
 
            // Add a button to the form
            AddButton();
 
            // Events
            form.add_BeforeTransaction(OnBeforeTransaction);
            form.add_BeforeUnload(OnBeforeUnload);
 
            console.WriteLine("Script initialized.");
 
        } catch (e) {
            console.WriteLine(FormatException("Init", null, e));
        }
    }
 
    // event handlers
    public function OnBeforeTransaction(sender: Object, e: CancelTransactionEventArgs)
    {
        // test for good transaction
        if (e.TransactionError)
            return;
 
        // no action on delete
        if (e.FunctionCode == "D")
            return;
 
        // Don't allow add transaction if there is a match on ADD
        if (e.FunctionCode == "A")
        {
            try {
                // Field values
                var taxid   = form.GetElementValue("VEN-TAX-ID");
                var vVendor = form.GetElementValue("VEN-VENDOR");
 
                // no action if the user has not entered a value
                if (taxid.length > 0)
                {
                    // build up the Data Service call
                    var sProd       = form.GetUserAttribute("productline");
                    var sFile       = "APVENMAST";
                    var sField      = "TAX-ID;VENDOR;VENDOR-GROUP";
                    var sIndex      = "";
                    var sCond       = "";
                    var sSelect     = "TAX-ID=" + taxid + "%26VENDOR-STATUS^%3DA";
                    var sMax        = "";
 
                    // Pass the variables for the API to DataService_Execute
                    var aDataAPI    = DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);
 
                    console.WriteLine("aDataAPI.length: " + aDataAPI.length);
 
                    // Did we get anything back from the call?
                    if(aDataAPI.length > 0)
                    {
                        var vendorList  = "\n";
                        var vendorVal   = "";
                        var i;
                        for(i = 0; i < aDataAPI.length; i++)
                        {
                            console.WriteLine(aDataAPI[i]);
 
                            // Build a list of vendors
                            vendorList += aDataAPI[i] + "\n";
                        }
 
                        var message = "Tax ID supplied matches vendor(s): " + vendorList + ". Transaction stopped.";
                        ConfirmDialog.ShowWarningDialog("Matching Vendor(s)", message, null);
 
                        form.SetMessage(message);
                        e.Cancel = true;
                    }
                    else{
                        console.WriteLine("***No Records***");
                    }
                }
                else
                {
                    form.SetMessage("Tax ID not verified while blank");
                }
            } catch (ex) {
                console.WriteLine(FormatException("OnBeforeTransaction", null, ex));
            }
        }
    }
 
    public function OnBeforeUnload(sender: Object, e: FormEventArgs)
    {
        // perform cleanup
        form.remove_BeforeTransaction(OnBeforeTransaction);
        form.remove_BeforeUnload(OnBeforeUnload);
        button.remove_Click(OnButtonClick);
    }
 
    public function OnButtonClick(sender: Object, e: RoutedEventArgs)
    {
        try {
            // Field values
            var taxid   = form.GetElementValue("VEN-TAX-ID");
            var vVendor = form.GetElementValue("VEN-VENDOR");
 
            // no action if the user has not entered a value
            if (taxid.length > 0)
            {
                // build up the Data Service call
                var sProd       = form.GetUserAttribute("productline");
                var sFile       = "APVENMAST";
                var sField      = "TAX-ID;VENDOR;VENDOR-GROUP";
                var sIndex      = "";
                var sCond       = "";
                var sSelect     = "TAX-ID=" + taxid + "%26VENDOR-STATUS^%3DA%26VENDOR!=" + vVendor;
                var sMax        = "";
 
                // Pass the variables for the API to DataService_Execute
                var aDataAPI    = DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);
 
                console.WriteLine("aDataAPI.length: " + aDataAPI.length);
 
                // Did we get anything back from the call?
                if(aDataAPI.length > 0)
                {
                    var vendorList  = "\n";
                    var vendorVal   = "";
                    var i;
                    for(i = 0; i < aDataAPI.length; i++)
                    {
                        console.WriteLine(aDataAPI[i]);
 
                        // Build a list of vendors
                        vendorList += aDataAPI[i] + "\n";
                    }
 
                    var message = "Tax ID supplied matches vendor(s): " + vendorList;
                    ConfirmDialog.ShowWarningDialog("Matching Vendor(s)", message, null);
                }
                else
                {
                    ConfirmDialog.ShowSuccessDialog("Tax ID Verified as Unique", "No matching Tax ID's found", null);
                }
            }
            else
            {
                form.SetMessage("Tax ID not verified while blank");
            }
 
        } catch (ex) {
            console.WriteLine(FormatException("OnButtonClick", null, ex));
        }
    }
 
    /**
     * DataService_Execute - This method returns an array for the api specified
     * Detail description
     * This method returns an array of values for for the api details
     * @param      required     sProd, PROD, defaults to user profile if not set - required
     * @param      required     sFile, FILE
     * @param      required     sField, FIELD
     * @param      optional     sIndex, INDEX, removed from api if not set
     * @param      optional     sCond, COND
     * @param      optional     sSelect, SELECT
     * @param      optional     sMax, MAX, defaults to 0 if not set
     * @access     private
     * @return     array
     *
     * Example:
     *
     *
 
        private function RunDataMine()
        {
            // build up the Data Service call
            var sProd       = form.GetUserAttribute("productline");
            var sFile       = "CUCODES";
            var sField      = "CURRENCY-CODE;DESCRIPTION";
            var sIndex      = "CUCSET1";
            var sCond       = "";
            var sSelect     = "";
            var sMax        = "";
 
            // Pass the variables for the API to DataService_Execute
            var aDataAPI    = DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);
 
            console.WriteLine("aDataAPI.length: " + aDataAPI.length);
 
            // Did we get anything back from the call?
            if(aDataAPI.length > 0)
            {
                var i = 0;
                for(i = 0; i < aDataAPI.length; i++)
                {
                    console.WriteLine(aDataAPI[i]);
                }
            }
            else{
                console.WriteLine("***No Records***");
            }
        }
 
    */
    private function DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax)
    {
        var a       = new Array();
        var aFields = new Array();
        var i       = 0;
        var s       = "";
        var oXML;
        var oRecs;
        var oRecNum;
        var oRec;
        var oFields;
 
        // Productline sProd empty, set from profile
        if(sProd == ""){sProd = form.GetUserAttribute("productline");}
 
        // Max sMax empty, set to 0 for all
        if(sMax == ""){sMax = 0;}
 
        // Build the complete Data Service Call
        s = ScriptConstants.DataMinePath + "?PROD=" + sProd + "&FILE=" + sFile + "&FIELD=" + sField;
 
        // If Index we add Index to the call
        if(sIndex != ""){s += "&INDEX=" + sIndex;}
 
        // The rest of the call
        s += "&COND=" + sCond + "&SELECT=" + sSelect + "&MAX=" + sMax +
            "&OUT=XML&DELIM="+ new Date().getTime(); // Time used to prevent caching
 
        console.WriteLine("s: " + s);
 
        // Make the server request, record the time it took
        var bTime   = new Date().getTime();
        oXML        = ScriptUtil.ServerRequest(s);
        var eTime   = new Date().getTime();
        console.WriteLine("API Execution Time: " + (eTime-bTime)/1000 + "seconds");
 
        // Get the Record Count Node
        oRecs   = oXML.SelectSingleNode("//RECORDS");
        oRecNum = oRecs != null ? oRecs.ChildNodes.Count : 0;
 
        console.WriteLine("oRecNum: " +oRecNum);
 
        // Determine if records were returned
        if(oRecNum == 0)
        {
            console.WriteLine("Data Service Call\n\n" + s + "\n\n returned " + oRecNum + " records.");
            return a;
        }
 
        // Build an array with the results
        for(oRec in oRecs.ChildNodes)
        {
            oFields = oRec.SelectSingleNode("./COLS");
            aFields = new Array();
            for(i = 0; i < oFields.ChildNodes.Count; i++)
            {
                aFields[aFields.length] = oFields.ChildNodes[i].InnerText;
            }
            a[a.length] = aFields;
        }
        return a;
    }
 
    // private functions
    private function AddButton()
    {
        button = new Button();
        button.Name = "TaxButton";
        button.Content = "Verify Tax ID";
        button.ToolTip = "Verify Tax ID Unique";
        button.IsEnabled = true;
        var size = 14;
        button.Width = (ScriptConstants.DefaultColumnWidth * size);
        button.add_Click(OnButtonClick);
        Grid.SetColumn(button, 5);
        Grid.SetRow(button, 2);
        Grid.SetColumnSpan(button, size);
        Grid.SetRowSpan(button, 1);
        form.AddCustomElement(form.GetTabPageContainer("TF0-0"), button);
    }
 
    private function FormatException(funcName, prefMsg, e)
    {
        var errMsg = (typeof(prefMsg)=="string" ? prefMsg+"\n" : "Exception encountered:\n");
        errMsg += "  Class:\t\tJjgAP10CheckTaxID\n";
        errMsg += "  Function:\t"+funcName+"\n";
        errMsg += "  Name:\t\t" + e.name + "\n"
        errMsg += "  Number:\t" + (e.number & 0xFFFF) + "\n"
        errMsg += "  Message:\t" + e.message + "\n"
        errMsg += "  Description:\t" + e.description + "\n"
        return errMsg;
    }
} }
//-----------------------------------------------------------------------------
//	JScript Example
//	Created by: 	Josh Geving - Solutions Group
//
//	Description: 	When entering a new vendor a button is provided to
//					query the system to determine if the tax-id entered
//					is unique, if not unique the vendor(s) with the matching
//					tax-id id are displayed
//
//	Last Tested on Smart Office Version 10.0.1.5
//-----------------------------------------------------------------------------

import System;
import System.Windows;
import System.Windows.Controls;
import S3.Client.Forms;
import System.Collections;
import System.Collections.Generic;
import System.Windows.Data;
import Mango.UI;
import Mango.UI.Core;
import Mango.UI.Services;

package S3.Client.Forms.JScript {

class JjgAP10CheckTaxID
{
	var console, form, formGrid, button;

	public function Init(element: Object, args: Object, controller : Object, debug : Object)
	{
		try {
			form = controller;
			formGrid = form.FormGrid;
			console = debug;

			console.WriteLine("Script initializing...");
			if (element != null)
				console.WriteLine("Connected element: " + element.Name);

			// Add a button to the form
			AddButton();

			// Events
			form.add_BeforeTransaction(OnBeforeTransaction);
			form.add_BeforeUnload(OnBeforeUnload);

			console.WriteLine("Script initialized.");

		} catch (e) {
			console.WriteLine(FormatException("Init", null, e));
		}
	}

	// event handlers
	public function OnBeforeTransaction(sender: Object, e: CancelTransactionEventArgs)
	{
		// test for good transaction
		if (e.TransactionError)
			return;

		// no action on delete
		if (e.FunctionCode == "D")
			return;

		// Don't allow add transaction if there is a match on ADD
		if (e.FunctionCode == "A")
		{
			try {
				// Field values
				var taxid 	= form.GetElementValue("VEN-TAX-ID");
				var vVendor	= form.GetElementValue("VEN-VENDOR");

				// no action if the user has not entered a value
				if (taxid.length > 0)
				{
					// build up the Data Service call
					var sProd 		= form.GetUserAttribute("productline");
					var sFile 		= "APVENMAST";
					var sField		= "TAX-ID;VENDOR;VENDOR-GROUP";
					var sIndex 		= "";
					var sCond 		= "";
					var sSelect		= "TAX-ID=" + taxid + "%26VENDOR-STATUS^%3DA";
					var sMax 		= "";

					// Pass the variables for the API to DataService_Execute
					var aDataAPI 	= DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);

					console.WriteLine("aDataAPI.length: " + aDataAPI.length);

					// Did we get anything back from the call?
					if(aDataAPI.length > 0)
					{
						var vendorList 	= "\n";
						var vendorVal	= "";
						var i;
						for(i = 0; i < aDataAPI.length; i++)
						{
							console.WriteLine(aDataAPI[i]);

							// Build a list of vendors
							vendorList += aDataAPI[i] + "\n";
						}

						var message = "Tax ID supplied matches vendor(s): " + vendorList + ". Transaction stopped.";
						ConfirmDialog.ShowWarningDialog("Matching Vendor(s)", message, null);

						form.SetMessage(message);
						e.Cancel = true;
					}
					else{
						console.WriteLine("***No Records***");
					}
				}
				else
				{
					form.SetMessage("Tax ID not verified while blank");
				}
			} catch (ex) {
				console.WriteLine(FormatException("OnBeforeTransaction", null, ex));
			}
		}
	}

	public function OnBeforeUnload(sender: Object, e: FormEventArgs)
	{
		// perform cleanup
		form.remove_BeforeTransaction(OnBeforeTransaction);
		form.remove_BeforeUnload(OnBeforeUnload);
		button.remove_Click(OnButtonClick);
	}

	public function OnButtonClick(sender: Object, e: RoutedEventArgs)
	{
		try {
			// Field values
			var taxid 	= form.GetElementValue("VEN-TAX-ID");
			var vVendor	= form.GetElementValue("VEN-VENDOR");

			// no action if the user has not entered a value
			if (taxid.length > 0)
			{
				// build up the Data Service call
				var sProd 		= form.GetUserAttribute("productline");
				var sFile 		= "APVENMAST";
				var sField		= "TAX-ID;VENDOR;VENDOR-GROUP";
				var sIndex 		= "";
				var sCond 		= "";
				var sSelect		= "TAX-ID=" + taxid + "%26VENDOR-STATUS^%3DA%26VENDOR!=" + vVendor;
				var sMax 		= "";

				// Pass the variables for the API to DataService_Execute
				var aDataAPI 	= DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);

				console.WriteLine("aDataAPI.length: " + aDataAPI.length);

				// Did we get anything back from the call?
				if(aDataAPI.length > 0)
				{
					var vendorList 	= "\n";
					var vendorVal	= "";
					var i;
					for(i = 0; i < aDataAPI.length; i++)
					{
						console.WriteLine(aDataAPI[i]);

						// Build a list of vendors
						vendorList += aDataAPI[i] + "\n";
					}

					var message = "Tax ID supplied matches vendor(s): " + vendorList;
					ConfirmDialog.ShowWarningDialog("Matching Vendor(s)", message, null);
				}
				else
				{
					ConfirmDialog.ShowSuccessDialog("Tax ID Verified as Unique", "No matching Tax ID's found", null);
				}
			}
			else
			{
				form.SetMessage("Tax ID not verified while blank");
			}

		} catch (ex) {
			console.WriteLine(FormatException("OnButtonClick", null, ex));
		}
	}

	/**
	 * DataService_Execute - This method returns an array for the api specified
	 * Detail description
	 * This method returns an array of values for for the api details
	 * @param      required 	sProd, PROD, defaults to user profile if not set - required
	 * @param      required		sFile, FILE
	 * @param      required		sField, FIELD
	 * @param      optional		sIndex, INDEX, removed from api if not set
	 * @param      optional		sCond, COND
	 * @param      optional		sSelect, SELECT
	 * @param      optional		sMax, MAX, defaults to 0 if not set
	 * @access     private
	 * @return     array
	 *
	 * Example:
	 *
	 *

		private function RunDataMine()
		{
			// build up the Data Service call
			var sProd 		= form.GetUserAttribute("productline");
			var sFile 		= "CUCODES";
			var sField		= "CURRENCY-CODE;DESCRIPTION";
			var sIndex 		= "CUCSET1";
			var sCond 		= "";
			var sSelect		= "";
			var sMax 		= "";

			// Pass the variables for the API to DataService_Execute
			var aDataAPI 	= DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);

			console.WriteLine("aDataAPI.length: " + aDataAPI.length);

			// Did we get anything back from the call?
			if(aDataAPI.length > 0)
			{
				var i = 0;
				for(i = 0; i < aDataAPI.length; i++)
				{
					console.WriteLine(aDataAPI[i]);
				}
			}
			else{
				console.WriteLine("***No Records***");
			}
		}

	*/
	private function DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax)
	{
		var a 		= new Array();
		var aFields = new Array();
		var i 		= 0;
		var s 		= "";
		var oXML;
		var oRecs;
		var oRecNum;
		var oRec;
		var oFields;

		// Productline sProd empty, set from profile
		if(sProd == ""){sProd = form.GetUserAttribute("productline");}

		// Max sMax empty, set to 0 for all
		if(sMax == ""){sMax = 0;}

		// Build the complete Data Service Call
		s = ScriptConstants.DataMinePath + "?PROD=" + sProd + "&FILE=" + sFile + "&FIELD=" + sField;

		// If Index we add Index to the call
		if(sIndex != ""){s += "&INDEX=" + sIndex;}

		// The rest of the call
		s += "&COND=" + sCond + "&SELECT=" + sSelect + "&MAX=" + sMax +
			"&OUT=XML&DELIM="+ new Date().getTime(); // Time used to prevent caching

		console.WriteLine("s: " + s);

		// Make the server request, record the time it took
		var bTime 	= new Date().getTime();
		oXML 		= ScriptUtil.ServerRequest(s);
		var eTime 	= new Date().getTime();
		console.WriteLine("API Execution Time: " + (eTime-bTime)/1000 + "seconds");

		// Get the Record Count Node
		oRecs 	= oXML.SelectSingleNode("//RECORDS");
		oRecNum = oRecs != null ? oRecs.ChildNodes.Count : 0;

		console.WriteLine("oRecNum: " +oRecNum);

		// Determine if records were returned
		if(oRecNum == 0)
		{
			console.WriteLine("Data Service Call\n\n" + s + "\n\n returned " + oRecNum + " records.");
			return a;
		}

		// Build an array with the results
		for(oRec in oRecs.ChildNodes)
		{
			oFields = oRec.SelectSingleNode("./COLS");
			aFields = new Array();
			for(i = 0; i < oFields.ChildNodes.Count; i++)
			{
				aFields[aFields.length] = oFields.ChildNodes[i].InnerText;
			}
			a[a.length] = aFields;
		}
		return a;
	}

	// private functions
	private function AddButton()
	{
		button = new Button();
		button.Name = "TaxButton";
		button.Content = "Verify Tax ID";
		button.ToolTip = "Verify Tax ID Unique";
		button.IsEnabled = true;
		var size = 14;
		button.Width = (ScriptConstants.DefaultColumnWidth * size);
		button.add_Click(OnButtonClick);
		Grid.SetColumn(button, 5);
		Grid.SetRow(button, 2);
		Grid.SetColumnSpan(button, size);
		Grid.SetRowSpan(button, 1);
		form.AddCustomElement(form.GetTabPageContainer("TF0-0"), button);
	}

	private function FormatException(funcName, prefMsg, e)
	{
		var errMsg = (typeof(prefMsg)=="string" ? prefMsg+"\n" : "Exception encountered:\n");
		errMsg += "  Class:\t\tJjgAP10CheckTaxID\n";
		errMsg += "  Function:\t"+funcName+"\n";
		errMsg += "  Name:\t\t" + e.name + "\n"
		errMsg += "  Number:\t" + (e.number & 0xFFFF) + "\n"
		errMsg += "  Message:\t" + e.message + "\n"
		errMsg += "  Description:\t" + e.description + "\n"
		return errMsg;
	}
} }

 

 

Data Service – Snippet for Smart Office Scripting

The following code can be used as a Snippet within the Lawson Smart Office Scripting Tool to perform a Data Service to retrieve data from S3 applications.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    /**
     * DataService_Execute - This method returns an array for the api specified
     * Detail description
     * This method returns an array of values for for the api details
     * @param      required     sProd, PROD, defaults to user profile if not set - required
     * @param      required     sFile, FILE
     * @param      required     sField, FIELD
     * @param      optional     sIndex, INDEX, removed from api if not set
     * @param      optional     sCond, COND
     * @param      optional     sSelect, SELECT
     * @param      optional     sMax, MAX, defaults to 0 if not set
     * @access     private
     * @return     array
     *
     * Example:
     *
     *
 
        private function RunDataMine()
        {
            // build up the Data Service call
            var sProd       = form.GetUserAttribute("productline");
            var sFile       = "CUCODES";
            var sField      = "CURRENCY-CODE;DESCRIPTION";
            var sIndex      = "CUCSET1";
            var sCond       = "";
            var sSelect     = "";
            var sMax        = "";
 
            // Pass the variables for the API to DataService_Execute
            var aDataAPI    = DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);
 
            console.WriteLine("aDataAPI.length: " + aDataAPI.length);
 
            // Did we get anything back from the call?
            if(aDataAPI.length > 0)
            {
                var i = 0;
                for(i = 0; i < aDataAPI.length; i++)
                {
                    console.WriteLine(aDataAPI[i]);
                }
            }
            else{
                console.WriteLine("***No Records***");
            }
        }
 
    */
    private function DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax)
    {
        var a       = new Array();
        var aFields = new Array();
        var i       = 0;
        var s       = "";
        var oXML;
        var oRecs;
        var oRecNum;
        var oRec;
        var oFields;
 
        // Productline sProd empty, set from profile
        if(sProd == ""){sProd = form.GetUserAttribute("productline");}
 
        // Max sMax empty, set to 0 for all
        if(sMax == ""){sMax = 0;}
 
        // Build the complete Data Service Call
        s = ScriptConstants.DataMinePath + "?PROD=" + sProd + "&FILE=" + sFile + "&FIELD=" + sField;
 
        // If Index we add Index to the call
        if(sIndex != ""){s += "&INDEX=" + sIndex;}
 
        // The rest of the call
        s += "&COND=" + sCond + "&SELECT=" + sSelect + "&MAX=" + sMax +
            "&OUT=XML&DELIM="+ new Date().getTime(); // Time used to prevent caching
 
        console.WriteLine("s: " + s);
 
        // Make the server request, record the time it took
        var bTime   = new Date().getTime();
        oXML        = ScriptUtil.ServerRequest(s);
        var eTime   = new Date().getTime();
        console.WriteLine("API Execution Time: " + (eTime-bTime)/1000 + "seconds");
 
        // Get the Record Count Node
        oRecs   = oXML.SelectSingleNode("//RECORDS");
        oRecNum = oRecs != null ? oRecs.ChildNodes.Count : 0;
 
        console.WriteLine("oRecNum: " +oRecNum);
 
        // Determine if records were returned
        if(oRecNum == 0)
        {
            console.WriteLine("Data Service Call\n\n" + s + "\n\n returned " + oRecNum + " records.");
            return a;
        }
 
        // Build an array with the results
        for(oRec in oRecs.ChildNodes)
        {
            oFields = oRec.SelectSingleNode("./COLS");
            aFields = new Array();
            for(i = 0; i < oFields.ChildNodes.Count; i++)
            {
                aFields[aFields.length] = oFields.ChildNodes[i].InnerText;
            }
            a[a.length] = aFields;
        }
        return a;
    }
	/**
	 * DataService_Execute - This method returns an array for the api specified
	 * Detail description
	 * This method returns an array of values for for the api details
	 * @param      required 	sProd, PROD, defaults to user profile if not set - required
	 * @param      required		sFile, FILE
	 * @param      required		sField, FIELD
	 * @param      optional		sIndex, INDEX, removed from api if not set
	 * @param      optional		sCond, COND
	 * @param      optional		sSelect, SELECT
	 * @param      optional		sMax, MAX, defaults to 0 if not set
	 * @access     private
	 * @return     array
	 *
	 * Example:
	 *
	 *

		private function RunDataMine()
		{
			// build up the Data Service call
			var sProd 		= form.GetUserAttribute("productline");
			var sFile 		= "CUCODES";
			var sField		= "CURRENCY-CODE;DESCRIPTION";
			var sIndex 		= "CUCSET1";
			var sCond 		= "";
			var sSelect		= "";
			var sMax 		= "";

			// Pass the variables for the API to DataService_Execute
			var aDataAPI 	= DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax);

			console.WriteLine("aDataAPI.length: " + aDataAPI.length);

			// Did we get anything back from the call?
			if(aDataAPI.length > 0)
			{
				var i = 0;
				for(i = 0; i < aDataAPI.length; i++)
				{
					console.WriteLine(aDataAPI[i]);
				}
			}
			else{
				console.WriteLine("***No Records***");
			}
		}

	*/
	private function DataService_Execute(sProd,sFile, sField, sIndex, sCond, sSelect, sMax)
	{
		var a 		= new Array();
		var aFields = new Array();
		var i 		= 0;
		var s 		= "";
		var oXML;
		var oRecs;
		var oRecNum;
		var oRec;
		var oFields;

		// Productline sProd empty, set from profile
		if(sProd == ""){sProd = form.GetUserAttribute("productline");}

		// Max sMax empty, set to 0 for all
		if(sMax == ""){sMax = 0;}

		// Build the complete Data Service Call
		s = ScriptConstants.DataMinePath + "?PROD=" + sProd + "&FILE=" + sFile + "&FIELD=" + sField;

		// If Index we add Index to the call
		if(sIndex != ""){s += "&INDEX=" + sIndex;}

		// The rest of the call
		s += "&COND=" + sCond + "&SELECT=" + sSelect + "&MAX=" + sMax +
			"&OUT=XML&DELIM="+ new Date().getTime(); // Time used to prevent caching

		console.WriteLine("s: " + s);

		// Make the server request, record the time it took
		var bTime 	= new Date().getTime();
		oXML 		= ScriptUtil.ServerRequest(s);
		var eTime 	= new Date().getTime();
		console.WriteLine("API Execution Time: " + (eTime-bTime)/1000 + "seconds");

		// Get the Record Count Node
		oRecs 	= oXML.SelectSingleNode("//RECORDS");
		oRecNum = oRecs != null ? oRecs.ChildNodes.Count : 0;

		console.WriteLine("oRecNum: " +oRecNum);

		// Determine if records were returned
		if(oRecNum == 0)
		{
			console.WriteLine("Data Service Call\n\n" + s + "\n\n returned " + oRecNum + " records.");
			return a;
		}

		// Build an array with the results
		for(oRec in oRecs.ChildNodes)
		{
			oFields = oRec.SelectSingleNode("./COLS");
			aFields = new Array();
			for(i = 0; i < oFields.ChildNodes.Count; i++)
			{
				aFields[aFields.length] = oFields.ChildNodes[i].InnerText;
			}
			a[a.length] = aFields;
		}
		return a;
	}

 

Copy the code and save as DataService.jss, for example, or copy directly into the Script tool and Save Selection as Snippet.

 

Transaction Service – Snippet for Smart Office Scripting

The following code can be used as a Snippet within the Lawson Smart Office Scripting tool for performing an S3 transaction.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    /**
     * TransactionService_Execute - This method returns xml from a transaction service call
     * Detail description
     * This method returns xml for the api details
     * @param      required     sForm, _TKN
     * @param      required     sProd, _PDL
     * @param      required     sFunction, FC
     * @param      required     sCall
     * @param      optional     sDesc
     * @access     private
     * @return     xml
     *
     * Example:
     *
 
        private function RunTransaction()
        {
            // Build the Transaction API
            var sCall       = "&CUC-CURRENCY-CODE=USD";
 
            // Transaction API values
            var sForm       = "CU01.1";
            var sProd       = form.GetUserAttribute("productline");
            var sFunction   = "I";
            var sDesc       = "Currency Inquire";   
 
            // Issue the Transaction API
            var TransXml    = TransactionService_Execute(sForm, sProd, sFunction, sCall, sDesc);
 
            // Do we want to see the xml that came back?
            console.WriteLine(TransXml.OuterXml);
 
            // Fetch a node by name and write out the contents
            console.WriteLine("CUC-CURRENCY-CODE: " + Transaction_GetFieldValue(TransXml, "CUC-CURRENCY-CODE"));
 
        }
 
    */
    private function TransactionService_Execute(sForm, sProd, sFunction, sCall, sDesc)
    {
        var s = "";
        var oXML;
 
        // Build the complete Transaction Service Call
        s = ScriptConstants.TransactionPath
        s += "?_PDL=" + sProd;
        s += "&_TKN=" + sForm
        if(sFunction == "Add" || sFunction == "A")
            {s += "&_EVT=ADD"}
        else
            {s += "&_EVT=CHG"}
        s += "&FC=" + sFunction;
        s += sCall;
        s += "&_LFN=ALL&_TDS=IGNORE&_OUT=XML&_EOT=TRUE";
 
        console.WriteLine("s: " + s);
 
        // Make the server request
        oXML = form.ServerRequest(s);
 
        // Determine if the Transaction Service Call processed
        if(!oXML)
        {
            console.WriteLine("The Transaction Service Call \n\n" + sDesc + "\n\nfailed to process.")
        }
        else if(Transaction_GetFieldValue(oXML, "MsgNbr") != "000")     // Determine if the Transaction Service Call worked
        {
            console.WriteLine(sForm + " MsgNbr: " + Transaction_GetFieldValue(oXML, "Message"));
        }
 
        return oXML;
    }
 
    private function Transaction_GetFieldValue(oData, sFind)
    {
        return oData.SelectSingleNode("//" + sFind).InnerText;
    }
	/**
	 * TransactionService_Execute - This method returns xml from a transaction service call
	 * Detail description
	 * This method returns xml for the api details
	 * @param      required 	sForm, _TKN
	 * @param      required		sProd, _PDL
	 * @param      required		sFunction, FC
	 * @param      required		sCall
	 * @param      optional		sDesc
	 * @access     private
	 * @return     xml
	 *
	 * Example:
	 *

		private function RunTransaction()
		{
			// Build the Transaction API
			var sCall 		= "&CUC-CURRENCY-CODE=USD";

			// Transaction API values
			var sForm		= "CU01.1";
			var sProd 		= form.GetUserAttribute("productline");
			var sFunction	= "I";
			var sDesc 		= "Currency Inquire";	

			// Issue the Transaction API
			var TransXml 	= TransactionService_Execute(sForm, sProd, sFunction, sCall, sDesc);

			// Do we want to see the xml that came back?
			console.WriteLine(TransXml.OuterXml);

			// Fetch a node by name and write out the contents
			console.WriteLine("CUC-CURRENCY-CODE: " + Transaction_GetFieldValue(TransXml, "CUC-CURRENCY-CODE"));

		}

	*/
	private function TransactionService_Execute(sForm, sProd, sFunction, sCall, sDesc)
	{
		var s = "";
		var oXML;

		// Build the complete Transaction Service Call
		s = ScriptConstants.TransactionPath
		s += "?_PDL=" + sProd;
		s += "&_TKN=" + sForm
		if(sFunction == "Add" || sFunction == "A")
			{s += "&_EVT=ADD"}
		else
			{s += "&_EVT=CHG"}
		s += "&FC=" + sFunction;
		s += sCall;
		s += "&_LFN=ALL&_TDS=IGNORE&_OUT=XML&_EOT=TRUE";

		console.WriteLine("s: " + s);

		// Make the server request
		oXML = form.ServerRequest(s);

		// Determine if the Transaction Service Call processed
		if(!oXML)
		{
			console.WriteLine("The Transaction Service Call \n\n" + sDesc + "\n\nfailed to process.")
		}
		else if(Transaction_GetFieldValue(oXML, "MsgNbr") != "000")		// Determine if the Transaction Service Call worked
		{
			console.WriteLine(sForm + " MsgNbr: " + Transaction_GetFieldValue(oXML, "Message"));
		}

		return oXML;
	}

	private function Transaction_GetFieldValue(oData, sFind)
	{
		return oData.SelectSingleNode("//" + sFind).InnerText;
	}

 

Copy the code above into the Script Tool.  Then highlight the section and choose Script > Save Selection as Snippet.

 

Using a Mashup to Provide Data for a Process Flow

In this example we are using a mashup created with the Mashup Designer to provide a user with a form. The purpose of the form is to collect information from the user and pass it into a waiting Process Flow Service. From there you can do whatever you need with the data.  Specifically, this example is for an employee to select another employee to act as proxy while they are away.

Needs
  1. Default the current employee value into the employee field
  2. Provide the user with an ability to select another employee
  3. Provide date fields for start and end dates

The end result looks like this:

Here is where the user is allowed a select on Employee using a standard S3 Drillselect:

Date select in action:

After submitting the form:

The resulting data in an email sent from an email node in Process Flow.

Here is the completed xaml code where I have inserted comments for all important areas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<!--
Mashup Designer Example
Created by:     Josh Geving - Solutions Group
 
Description:    Simple Mashup form which provides an employee a form to select another employee
                    to act as a proxy. Form includes one defaulted value from user context, two date select
                    fields and an S3 Drillselect fro an employee value.  These values are passed to a waiting
                    Process Flow Service called EmployeeProxy (not included).
 
Last Tested:    LSO 9.1.3.7 - Mashup Designer 10.0.0
-->
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI" xmlns:ps="clr-namespace:PF.Client.Mashup;assembly=PF.Client" xmlns:s3="clr-namespace:S3.Client.Mashup;assembly=S3.Client" Name="MainGrid">
    <Grid.Resources>
    </Grid.Resources>
 
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Height="30" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
 
<!-- An example of an optional menu bar, could be removed if no menu bar will be used -->
    <!--
    <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Stretch" Height="40"
                     Style="{DynamicResource styleBackgroundApplicationBarMashup}">
        <Menu>
            <MenuItem Header="_File">
                <MenuItem Header="_New" />
                <Separator />
                <MenuItem Header="_Save" />
            </MenuItem>
        </Menu>
    </StackPanel>
    -->
 
    <!-- begin the tirgger panel tied to a Service and including VariableNames -->
    <ps:TriggerPanel Name="TriggerPanel" Service="EmployeeProxy" DataArea="LIVE" IsDataAreaInSession="True" VariableNames="COMMENT,ENDDATE,ORIGEMPLOYEE,PROXYEMPLOYEE,STARTDATE" MandatoryVariableNames="COMMENT,ORIGEMPLOYEE,PROXYEMPLOYEE,STARTDATE,ENDDATE" CriteriaName1="Criteria 1" CriteriaName2="Criteria 2" CriteriaName3="Criteria 3" Margin="20" Grid.Column="0" Grid.Row="2">
        <ps:TriggerPanel.Events>
            <!-- an event on Initialized to FillForm which allows us to set a value from the User Context (employee) -->
            <mashup:Events>
                <mashup:Event SourceName="TriggerPanel" SourceEventName="Initialized" TargetName="TriggerPanel" TargetEventName="FillForm">
                    <mashup:Parameter TargetKey="COMMENT" />
                    <mashup:Parameter TargetKey="ENDDATE" />
                    <mashup:Parameter TargetKey="ORIGEMPLOYEE" Value="{mashup:UserContextValue Path=S3/employee}" />
                    <mashup:Parameter TargetKey="PROXYEMPLOYEE" />
                    <mashup:Parameter TargetKey="STARTDATE" />
                </mashup:Event>
            </mashup:Events>
        </ps:TriggerPanel.Events>
 
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="8" />
                <ColumnDefinition Width="200" />
                <ColumnDefinition Width="100" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
 
            <!-- label and textbox to display the user context employee value, IsEnabled set to false to prevent user entry -->
            <Label Content="Employee" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
            <TextBox Text="{Binding [ORIGEMPLOYEE]}" Width="100" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="2" Name="EmployeeComboBox" IsEnabled="False" Margin="10" />
 
            <!-- label and drill select which is a standard S3 drill select, bound to PROXYEMPLOYEE -->
            <Label Content="Proxy Employee" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
            <s3:DrillSelectTextBox Text="{Binding [PROXYEMPLOYEE]}" Grid.Row="1" Grid.Column="2" Name="EmployeeSelect" Token="HR11.1" SystemCode="HR" KeyNumber="H07" KeyString="01=1" Height="12" IsSelectable="True" Margin="10" TrimValues="True" />
 
            <!-- label and datepicker, the key prt of this is to use SelectedDate for the Binding -->
            <Label Content="Start Date" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
            <DatePicker SelectedDate="{Binding [STARTDATE]}" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Left" Name="startDate" VerticalAlignment="Top" Margin="5" Width="120" />
 
            <!-- label and datepicker, the key prt of this is to use SelectedDate for the Binding -->
            <Label Content="End Date" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
            <DatePicker SelectedDate="{Binding [ENDDATE]}" Grid.Row="3" Grid.Column="2" HorizontalAlignment="Left" Name="endDate" VerticalAlignment="Top" Margin="5" Width="120" />
 
            <!-- label and textbox for the comment -->
            <Label Content="Comment" Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
            <TextBox Grid.Row="4" Grid.ColumnSpan="2" Name="CommentTextBox" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding [COMMENT]}" Margin="10" IsEnabled="True" />
 
            <!-- button with an event to trigger the flow -->
            <Button Grid.Row="5" Grid.ColumnSpan="3" HorizontalAlignment="Right" Content="Submit Proxy Request" Width="150" VerticalAlignment="Center" Margin="0,8,0,0">
                <Button.CommandParameter>
                    <mashup:Events>
                        <mashup:Event TargetEventName="TriggerFlow" TargetName="TriggerPanel" />
                    </mashup:Events>
                </Button.CommandParameter>
            </Button>
        </Grid>
    </ps:TriggerPanel>
 
    <!-- two additional labels up in the header for the user -->
    <Label Name="MainLabel" Content="Employee Proxy Request" Style="{DynamicResource styleGroupBoxHeaderMashup}" Margin="10,10,0,0" Grid.Column="0" Grid.Row="0" />
    <Label Name="SecondaryLabel" Content="Please fill in all fields below and submit your request" Grid.Column="0" Grid.Row="1" Margin="20,0,0,0" />
</Grid>
<!--
Mashup Designer Example
Created by: 	Josh Geving - Solutions Group

Description: 	Simple Mashup form which provides an employee a form to select another employee
					to act as a proxy. Form includes one defaulted value from user context, two date select
					fields and an S3 Drillselect fro an employee value.  These values are passed to a waiting
					Process Flow Service called EmployeeProxy (not included).

Last Tested: 	LSO 9.1.3.7 - Mashup Designer 10.0.0
-->
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI" xmlns:ps="clr-namespace:PF.Client.Mashup;assembly=PF.Client" xmlns:s3="clr-namespace:S3.Client.Mashup;assembly=S3.Client" Name="MainGrid">
	<Grid.Resources>
	</Grid.Resources>

	<Grid.ColumnDefinitions>
		<ColumnDefinition Width="1*" />
	</Grid.ColumnDefinitions>
	<Grid.RowDefinitions>
		<RowDefinition Height="40" />
		<RowDefinition Height="30" />
		<RowDefinition Height="Auto" />
	</Grid.RowDefinitions>

<!-- An example of an optional menu bar, could be removed if no menu bar will be used -->
	<!--
	<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Stretch" Height="40"
					 Style="{DynamicResource styleBackgroundApplicationBarMashup}">
		<Menu>
			<MenuItem Header="_File">
				<MenuItem Header="_New" />
				<Separator />
				<MenuItem Header="_Save" />
			</MenuItem>
		</Menu>
	</StackPanel>
	-->

	<!-- begin the tirgger panel tied to a Service and including VariableNames -->
	<ps:TriggerPanel Name="TriggerPanel" Service="EmployeeProxy" DataArea="LIVE" IsDataAreaInSession="True" VariableNames="COMMENT,ENDDATE,ORIGEMPLOYEE,PROXYEMPLOYEE,STARTDATE" MandatoryVariableNames="COMMENT,ORIGEMPLOYEE,PROXYEMPLOYEE,STARTDATE,ENDDATE" CriteriaName1="Criteria 1" CriteriaName2="Criteria 2" CriteriaName3="Criteria 3" Margin="20" Grid.Column="0" Grid.Row="2">
		<ps:TriggerPanel.Events>
			<!-- an event on Initialized to FillForm which allows us to set a value from the User Context (employee) -->
			<mashup:Events>
				<mashup:Event SourceName="TriggerPanel" SourceEventName="Initialized" TargetName="TriggerPanel" TargetEventName="FillForm">
					<mashup:Parameter TargetKey="COMMENT" />
					<mashup:Parameter TargetKey="ENDDATE" />
					<mashup:Parameter TargetKey="ORIGEMPLOYEE" Value="{mashup:UserContextValue Path=S3/employee}" />
					<mashup:Parameter TargetKey="PROXYEMPLOYEE" />
					<mashup:Parameter TargetKey="STARTDATE" />
				</mashup:Event>
			</mashup:Events>
		</ps:TriggerPanel.Events>

		<Grid>
			<Grid.ColumnDefinitions>
				<ColumnDefinition Width="Auto" />
				<ColumnDefinition Width="8" />
				<ColumnDefinition Width="200" />
				<ColumnDefinition Width="100" />
			</Grid.ColumnDefinitions>
			<Grid.RowDefinitions>
				<RowDefinition Height="Auto" />
				<RowDefinition Height="Auto" />
				<RowDefinition Height="Auto" />
				<RowDefinition Height="Auto" />
				<RowDefinition Height="Auto" />
				<RowDefinition Height="Auto" />
			</Grid.RowDefinitions>

			<!-- label and textbox to display the user context employee value, IsEnabled set to false to prevent user entry -->
			<Label Content="Employee" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
			<TextBox Text="{Binding [ORIGEMPLOYEE]}" Width="100" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="2" Name="EmployeeComboBox" IsEnabled="False" Margin="10" />

			<!-- label and drill select which is a standard S3 drill select, bound to PROXYEMPLOYEE -->
			<Label Content="Proxy Employee" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
			<s3:DrillSelectTextBox Text="{Binding [PROXYEMPLOYEE]}" Grid.Row="1" Grid.Column="2" Name="EmployeeSelect" Token="HR11.1" SystemCode="HR" KeyNumber="H07" KeyString="01=1" Height="12" IsSelectable="True" Margin="10" TrimValues="True" />

			<!-- label and datepicker, the key prt of this is to use SelectedDate for the Binding -->
			<Label Content="Start Date" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
			<DatePicker SelectedDate="{Binding [STARTDATE]}" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Left" Name="startDate" VerticalAlignment="Top" Margin="5" Width="120" />

			<!-- label and datepicker, the key prt of this is to use SelectedDate for the Binding -->
			<Label Content="End Date" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
			<DatePicker SelectedDate="{Binding [ENDDATE]}" Grid.Row="3" Grid.Column="2" HorizontalAlignment="Left" Name="endDate" VerticalAlignment="Top" Margin="5" Width="120" />

			<!-- label and textbox for the comment -->
			<Label Content="Comment" Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
			<TextBox Grid.Row="4" Grid.ColumnSpan="2" Name="CommentTextBox" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding [COMMENT]}" Margin="10" IsEnabled="True" />

			<!-- button with an event to trigger the flow -->
			<Button Grid.Row="5" Grid.ColumnSpan="3" HorizontalAlignment="Right" Content="Submit Proxy Request" Width="150" VerticalAlignment="Center" Margin="0,8,0,0">
				<Button.CommandParameter>
					<mashup:Events>
						<mashup:Event TargetEventName="TriggerFlow" TargetName="TriggerPanel" />
					</mashup:Events>
				</Button.CommandParameter>
			</Button>
		</Grid>
	</ps:TriggerPanel>

	<!-- two additional labels up in the header for the user -->
	<Label Name="MainLabel" Content="Employee Proxy Request" Style="{DynamicResource styleGroupBoxHeaderMashup}" Margin="10,10,0,0" Grid.Column="0" Grid.Row="0" />
	<Label Name="SecondaryLabel" Content="Please fill in all fields below and submit your request" Grid.Column="0" Grid.Row="1" Margin="20,0,0,0" />
</Grid>

.

Apply a Mask to the Vendor Tax ID Field

In this example we were asked to mask the Tax ID field on the Lawson S3 Vendor screen (AP10).  Under certain circumstances it may be necessary to protect this data. This was part of a project to provide users with a vendor look-up screen and verification of the vendor based on the last 4 digits of the Tax ID was part of the plan.

Here is the script that was used to mask the Tax ID data if a Tax ID was associated with the record. The field was also made output-only.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//-----------------------------------------------------------------------------
//  Smart Office Script Example
//  Created by:     Josh Geving
//
//  Description:    Mask the Tax ID field and only display the last 4
//                  characters
//
//  Last Tested:    9.1.3
//-----------------------------------------------------------------------------
import System;
import System.Windows;
import System.Windows.Controls;
import S3.Client.Forms;
 
import System.Collections;
import System.Collections.Generic;
import System.Windows.Data;
import Mango.UI;
import Mango.UI.Core;
import Mango.UI.Services;
 
package S3.Client.Forms.JScript {
 
class JJG_AP10_TAXIDMASK
{
    var console, form, formGrid;
 
    public function Init(element: Object, args: Object, controller: Object, debug: Object)
    {
        try {
            form = controller;
            formGrid = form.FormGrid;
            console = debug;
 
            // TODO Add your code here
 
            //lets make the field output only while we are at it
            var TaxIdField      = form.GetElement("VEN-TAX-ID");
            TaxIdField.IsEnabled = false;
 
            form.add_AfterTransaction(OnAfterTransaction);
 
            form.add_BeforeUnload(OnBeforeUnload);
 
        } catch (e) {
            console.WriteLine(ScriptUtil.FormatException("Init", e));
        }
    }
 
    // event handlers
    public function OnBeforeUnload(sender: Object, e: FormEventArgs)
    {
        // perform cleanup
 
        form.remove_BeforeUnload(OnBeforeUnload);
        form.remove_AfterTransaction(OnAfterTransaction);
    }
 
    // private functions
 
    public function OnAfterTransaction(sender: Object, e: TransactionEventArgs)
    {
        //store the tax id
        var vTaxId          = form.GetTransactionValue("VEN-TAX-ID");
 
        //set a variable that will be the masked version
        var vAsterisks      = "";
 
        //the length of the masked string as the fill
        var vFillLength     = (vTaxId.length-4);
 
        //perform a loop to fill in the asterisks based on the tax id length
        var i               = 0;
        while (i <= vFillLength){
            vAsterisks += "*";
            i++;
        }
 
        //the new masked tax id displaying the last 4 characters of the tax id
        var vMasked         = vAsterisks + vTaxId.substring(vTaxId.length-4,vTaxId.length);
 
        //set the value to the form and transaction
        form.SetElementValue("VEN-TAX-ID", vMasked);
        form.SetTransactionValue("VEN-TAX-ID", vMasked);
    }
} }
//-----------------------------------------------------------------------------
//	Smart Office Script Example
//	Created by: 	Josh Geving
//
//	Description: 	Mask the Tax ID field and only display the last 4
//					characters
//
//	Last Tested: 	9.1.3
//-----------------------------------------------------------------------------
import System;
import System.Windows;
import System.Windows.Controls;
import S3.Client.Forms;

import System.Collections;
import System.Collections.Generic;
import System.Windows.Data;
import Mango.UI;
import Mango.UI.Core;
import Mango.UI.Services;

package S3.Client.Forms.JScript {

class JJG_AP10_TAXIDMASK
{
	var console, form, formGrid;

	public function Init(element: Object, args: Object, controller: Object, debug: Object)
	{
		try {
			form = controller;
			formGrid = form.FormGrid;
			console = debug;

			// TODO Add your code here

			//lets make the field output only while we are at it
			var TaxIdField 		= form.GetElement("VEN-TAX-ID");
			TaxIdField.IsEnabled = false;

			form.add_AfterTransaction(OnAfterTransaction);

			form.add_BeforeUnload(OnBeforeUnload);

		} catch (e) {
			console.WriteLine(ScriptUtil.FormatException("Init", e));
		}
	}

	// event handlers
	public function OnBeforeUnload(sender: Object, e: FormEventArgs)
	{
		// perform cleanup

		form.remove_BeforeUnload(OnBeforeUnload);
		form.remove_AfterTransaction(OnAfterTransaction);
	}

	// private functions

	public function OnAfterTransaction(sender: Object, e: TransactionEventArgs)
	{
		//store the tax id
		var vTaxId	 		= form.GetTransactionValue("VEN-TAX-ID");

		//set a variable that will be the masked version
		var vAsterisks		= "";

		//the length of the masked string as the fill
		var vFillLength 	= (vTaxId.length-4);

		//perform a loop to fill in the asterisks based on the tax id length
		var i				= 0;
		while (i <= vFillLength){
			vAsterisks += "*";
			i++;
		}

		//the new masked tax id displaying the last 4 characters of the tax id
		var vMasked 		= vAsterisks + vTaxId.substring(vTaxId.length-4,vTaxId.length);

		//set the value to the form and transaction
		form.SetElementValue("VEN-TAX-ID", vMasked);
		form.SetTransactionValue("VEN-TAX-ID", vMasked);
	}
} }

 

Retrieving User Profile Values in a Mashup

The S3 application User Profile values are available from within a Mashup using the following syntax:

1
2
3
<Label Content="{mashup:UserContextValue Path=S3/id}" />
 
//id is an attribute returned by Profile denoting the user id
<Label Content="{mashup:UserContextValue Path=S3/id}" />

//id is an attribute returned by Profile denoting the user id

Using this same syntax it is possible to retrieve these other useful values:

  • email
  • firstname
  • lastname
  • name
  • productline
  • employee
  • vendor
  • vendor_group
  • company

Of course you can view the full list against your applications using the following:

http://<server>/servlet/Profile?

Add Attachment Capability to Forms in Landmark

Within the Landmark code it is very easy to add attachment functionality to different areas of the application. In this example we are adding attachments to the Session page within Lawson Talent Management.

Why was this done?

Customer wanted file attachment capability on Session

Where was this done?

Within the Persistent Fields of Session (bl) and Forms section of Session (ui).

 

Session.busclass (bl)

 Persistent Fields
...
 //SessionAttachment is the name we are giving the attachment field
 SessionAttachment is an Attachment

 

Session.busclass (ui)

Within the user interface file locate where you would like the attachment to display, in this case we are using the SessionContextForm.

//FORMS
 SessionContextForm is a Form
// Form used to define the Session
 ...
 ShortDescription
 //add field for attachment
 SessionAttachment.File
 label is "SessionAttachment"
 single column
 Description

Force an Employee to have a certain value before an Action occurs

Why was this done?

Customer wanted to restrict an action until criteria was met.

Where was this done?

Within the Action/Parameter Rules against the Employee.busclass (bl).

Special Notes

This was added to the Name rule to make sure it kicked off near the front.  Field was also added to the UI busclass.

 

 		RehireResource is an Instance RequestAction
			request action process is RehireResource

...

			Parameter Rules
...
				Name
					initial value is Employee.Name
					required

					//mod to force EligleForRehire true on rehire action
					constraint(Employee.EligibleForRehire)
						"EmployeeMustBeEligibleForRehire"

 

 

Add a Textarea counter on KeyUp

In this situation, we wanted to place a counter beneath a textarea on the form where we would display a running total of characters as the user typed.  A fairly common thing to come across on the web. This entailed a new function where we hard coded character limit of 240.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function FORM_OnInit()function FORM_OnInit()
{
    lawForm.getFormElement("textarea1").onkeyup = function(){characterCount();};
}
 
function characterCount()
{
    var vCharCount = lawForm.getFormValue("textarea1").length;
 
    if(vCharCount > 240)
    {
        var vSafeValue = lawForm.getFormValue("textarea1").substring(0, 240);
        lawForm.setFormValue("textarea1",vSafeValue);
        lawForm.setFormValue("text6","You hit the max");
    }
    else
    {
        lawForm.setFormValue("text6",vCharCount);
    }
}
function FORM_OnInit()function FORM_OnInit()
{
	lawForm.getFormElement("textarea1").onkeyup = function(){characterCount();};
}

function characterCount()
{
	var vCharCount = lawForm.getFormValue("textarea1").length;

	if(vCharCount > 240)
	{
		var vSafeValue = lawForm.getFormValue("textarea1").substring(0, 240);
		lawForm.setFormValue("textarea1",vSafeValue);
		lawForm.setFormValue("text6","You hit the max");
	}
	else
	{
		lawForm.setFormValue("text6",vCharCount);
	}
}

 

Which looks like this: