The scenario for this post is to be able to verify something on a panel in a M3 program before a request is submitted to the M3 BE server. The validation in the example will be made using a MI program that is called asynchronously. The example is not a realistic case but it is easy to test and can be modified and generalized for real business cases. Note that the script is just an example and not intended for production use.
Script overview
The script is intended to be used on the the E-panel in the MMS001 program. When the Requesting event is fired for the current panel the script will only allow some keys to be pressed, including F3,F4,F5 and F12. If any other key is pressed the script will cancel the Requesting event to prevent the request from running and then start the validation. The validation is done by loading user data for the item responsible from the MNS150MI program. The request will be allowed to execute if the facility for the item responsible matches one of the allowed facilities that are defined in the script. In case the facility is not allowed a warning dialog will be displayed for the user.
The functions in the script will be described in more detail below followed by some instructions for how to test the script. The script code can be found in the end of the post.
Init function
The Init function tries to find the item responsible (MMRESP) field and if it cannot be found the script will exit. Event handlers are attached to the Requesting event to be able to cancel requests and to the Requested event so that the event handlers can be disconnected later.
OnRequesting event handler
The script checks if a key has been pressed and if it is one of the allowed keys defined in the validKeys variable (F3,F4,F5,F12). If it is one of the allowed keys the request is allowed. In all other cases the request is cancelled by the setting the Cancel property to true on the CancelRequestEventArgs parameter. The validation is then started unless a validation is already running. The key that was pressed is also stored so that it can be pressed programatically if the validation succeeds.
OnRequested event handler
This function removes the event handlers and also sets the isUnloaded flag to indicate that the script is no longer in a valid state.
StartValidation function
The StartValidation function gets the responsible from the panel, constructs a MIRecord and then uses the MIWorker to call MNS150MI asynchronously. The mouse cursor is also set to busy.
OnResponse event handler
This event handler is always called when the MI program has completed, successfully or not. If there is an error or the script has been unloaded the script will exit.
The facility value is retrieved from the MIRecord and then then checked against the valid facilities in the validFacilities variable. If the facility value is valid the script sets the isValidated flag to indicate this and then uses the PressKey method on the controller to programatically press the key that was stored in the OnRequesting event handler. If the facility was not valid a warning dialog is shown to the user.
SetWaitCursor function
This is a helper function for setting the wait and default cursor for the program window.
Testing the script
1. Start MMS001 and navigate to the E-panel.
2. Open the Script Tool, load the script code or paste it from the web page.
3. Run the script and then click the Next button or the Enter key on the E-panel in MMS001.
4. Unless your user has the facility A01, B01 or C01 defined in MNS150 you should get the warning dialog and the next panel should not be loaded.
5. You can change the values of the validFacilities values in the script to test with different facilities. You can also change your facility in the E-panel in MNS150.

Script code
import System;
import System.Windows;
import System.Windows.Controls;
import System.Windows.Input;
import Lawson.M3.MI;
import Mango.UI;
import MForms;
package MForms.JScript {
class ValidateFieldWithMI {
var controller;
var debug;
var pressedKey;
var textBoxResponsible;
var isValidating = false;
var isValidated = false;
var isUnloaded = false;
var validKeys = "F3,F4,F5,F12";
var validFacilities = "A01,B01,C01";
public function Init(element : Object, args : Object, controller : Object, debug : Object) {
var content : Object = controller.RenderEngine.Content;
textBoxResponsible = ScriptUtil.FindChild(content, "MMRESP");
if (textBoxResponsible == null) {
debug.WriteLine("Responsible field not found");
return;
}
this.controller = controller;
this.debug = debug;
controller.add_Requesting(OnRequesting);
controller.add_Requested(OnRequested);
debug.WriteLine("Script initialized");
}
public function OnRequesting(sender : Object, e : CancelRequestEventArgs) {
if (isValidated || (e.CommandType == "KEY" && validKeys.Contains(e.CommandValue))) {
debug.WriteLine("Request allowed");
return;
}
if (!isValidating) {
pressedKey = e.CommandValue;
StartValidation();
}
e.Cancel = true;
debug.WriteLine("Request cancelled");
}
public function OnRequested(sender : Object, e : RequestEventArgs) {
isUnloaded = true;
controller.remove_Requesting(OnRequesting);
controller.remove_Requested(OnRequested);
debug.WriteLine("Script unloaded");
}
public function StartValidation() {
try {
var responsible = textBoxResponsible.Text;
debug.WriteLine("Starting validation for responsible " + responsible);
isValidating = true;
var record = new MIRecord();
record["USID"] = responsible;
MIWorker.Run("MNS150MI", "GetUserData", record, OnResponse);
SetWaitCursor(true);
} catch (ex) {
debug.WriteLine(ex);
}
}
public function OnResponse(response : MIResponse) {
SetWaitCursor(false);
if (response.HasError) {
debug.WriteLine("MIAccess error. " + response.Error.ToString());
return;
}
if (isUnloaded) {
return;
}
var record = response.Item;
var facility = record["FACI"];
if (validFacilities.Contains(facility)) {
debug.WriteLine("The facility " + facility + " is valid, sending " + pressedKey + " key.");
isValidated = true;
controller.PressKey(pressedKey);
} else {
var header = "The facility " + facility + " is valid not valid";
var message = "The item responsible " + textBoxResponsible.Text + " must belong to one of the following facilities: " + validFacilities;
debug.WriteLine(header);
ConfirmDialog.ShowWarningDialog(header, message, null);
}
isValidating = false;
}
public function SetWaitCursor(wait) {
var element = controller.Host.Implementation;
element.Cursor = wait ? Cursors.Wait : Cursors.Arrow;
element.ForceCursor = true;
}
}
}
I think this is a very useful scenario, thanks a lot Peter for taking the time to write this post.
Thanks!. Really nice and clean code.
Pingback: Calling M3 APIs | Developing for Infor Smart Office
Peter,
This is perhaps what I am looking for. I have a script on OIS101 that shows a text field where users key in a decimal value in order to recalculate the %Discount value but people in Europe can not use it because they use a comma decimal format instead of a period. I was thinkig to call MNS150MI from OIS100 to determine the user’s decimal format in order to replace the periods and commas accordingly. Could you please advice if there is an easier or native way for a script to manage the decimal formats same as LSO?
textBoxProductDiscount.Text = roundNumber(100 – Double.Parse(textBoxRatio.Text), 2);
Thank you,
Gaston