Smart Office SDK – First Project Part 4 – Searching for and Validating Update Methods

This is the 4th part in a series of posts exploring how I am looking at using the Smart Office SDK to eliminate (with extreme prejudice) a modification we call “the Vessel Mod”.

The postings have been tailored in a fashion to demonstrate the techniques and logic processes I use when exploring new tools and methods.

The 1st post ( discusses testing that we have the SDK installed and validating that we can manipulate Smart Office through the SDK by using the sample code from Infor – launching our own ‘features’, adding controls and subscribing to events.

The 2nd post ( discusses how I validated the core functionality which will drive our feature when creating a project from scratch. The emphasis is on writing code to take small steps and validating each of those steps.

The 3rd post ( we focus back on the modification itself and look at exploring its interactions with M3 from a user expectation perspective. We should not lose any benefits, only gain.

This post is about exploring the various methods that I need to use to provide a seamless user transition.

I decided to start with the most challenging aspect of my last post, the updating of the Vessel/Voyage dates against the delivery header (MWS410/I). Now it is worth noting that since we did our M3 10 Upgrade our modification hasn’t been working – it stopped updating the route and departure date in MWS410/I.

There is a shot of MWS410/I in all its glory.

Being somewhat eager to publish another article to my blog I decided to forgo the actual manual testing of the update (silly naïve muppet that I am) and dove right in.

First place to look, MRS001 – the API Repository

And what do you know, I can see MWS410MI – sounds too good to be true. Let us take a look at the transactions.

This is truly a ‘WTF!?’ moment – there’s almost nothing in here about manipulating the delivery. Take a look at DRSxxxMI programs, no dice. Start scouring the everywhere that I can think of and nothing…so desperate was I, that I actually did some asking around too…

All yielded the same lack of result…

Ok, so that cuts down our options – we know that we can go in to MWS410/I and update the route, we’ve visually seen that the field isn’t greyed out so we can enter a new value (silly naïve muppet). With this in mind we can use the M3 Automation functionality.

So I load up the M3 JScript developers guide and have a quick read up on the automation – well, probably more of a skim – or more I grabbed the example and tailored it a little rather than actually reading any real words 🙂

I came up with this:





Run it but it comes up with a prompt “Enter new departure date/time”.

Hmmm…hit ok, get the same message. Hit Cancel and the route Textbox has been changed, but the description hasn’t – so it hasn’t actually updated the record.

At this point I decided to try running through the process manually and I get exactly the same issue.

We’ll dump that avenue of exploration at the moment. We know that this doesn’t work properly in the existing modification and we’ve somehow managed to survive for a couple of years without it, so not likely to be a major drama. If things really come down to it, as we are really only using the route information for the purposes of the odd report then we could probably SQL the records – something I am loath to do and means that we have to be really really careful when we upgrade…

Going back to the order itself (OIS300), we can see that there are options such as “Dely Time Chg” – this could be promising. Run the program against an order – and the program says “M3 Customer Order. Print Delivery Time Chgs” – not helpful 😦

But we try again, and there is a Reschedule option – it has precisely no useful information in the Xtreme knowledgebase and none in companion. Some quick tests against an order and we can see it will indeed update the dates on the order.

Unfortunately this is on a line by line basis and we need to manipulate the contents of the ListView itself (New dt field). Not something that lends too well to Automation.

Examining the APIs under OIS100MI there is “UpdCnfDlyDate” – also looks like what OIS130 is doing. A quick test and it doesn’t appear to do anything that I can see 😦

But we have the sourcecode to M3, so lets take a look. Under ROOT\M3BE\env\Prod\Fix\MVX\TFix\src\mvx\app\pgm I find the class (if there weren’t any fixes for it, it would be under your base directory – mine being ROOT\M3BE\MVX\1412\base\src\mvx\app\pgm). Ok, so taking a look at the source it looks like it is manipulating the OOLINE tables OBPLDT, OBPLHM, OBDSDT, OBDSHM, OBCODT, OBCODZ, OBCOHM and OBCOHZ if there is a route, or OBCODT, and OBCODZ if there isn’t.

Quickly checking the database with WinSQL I can see that indeed it does actually do something – it’s just not visible where I was looking nor did it do what I wanted.

So, it’s back to having to deal with OIS130.

What I am going to do is take my test application and add a new button called “Insert Test URI” – this will simply inject an mforms automation URI to start OIS130. I’m also going to launch the task as a modal dialog box so I can retain control over the automation (DashboardTaskService.Current.LaunchTaskModal()). Launching a modal dialog is a new function under LSO10.

The URI I am going to insert is this:

mforms://_automation/?data=<?xml+version=\”1.0\”+encoding=\”utf-8\”?><sequence>    <step+command=\”RUN\”+value=\”OIS130\”+/>    <step+command=\”KEY\”+value=\”ENTER\”>        <field+name=\”WWQTTP\”>2</field>    </step>    <step+command=\”KEY\”+value=\”ENTER\”>        <field+name=\”WWORNO\”>0000092053</field>        </step>    </sequence>

It will nicely populate order number for me and ensure I am in the correct sort order.

But we still don’t really have a way to manipulate the date without a lot of hacking.

Interestingly I spoke to my staff (I know!) and they were updating the lines by ending the lines in the customer order (OIS101). Now I know that I can get to the lines fairly easily through OIS301 on panel A.

A simple Options -> Change and we get to OIS101/E

We can look at using automation to go to OIS301/A and the enter in our values, go to OES101/E, change the requested dely dt and we’re done! We will need to do it for each line.

So, quickly hacking together the automation steps I’m ready to test.

mforms://_automation/?data=<?xml version=”1.0″ encoding=”utf-8″?>

<step command=”RUN” value=”OIS301″ />
<step command=”KEY” value=”ENTER”>
<field name=”WWQTTP”>1</field>
<step command=”KEY” value=”ENTER”>
<field name=”W1OBKV”>0000092053</field>
<field name=”WWPSEQ”>E</field>
<step command=”LSTOPT” value=”2″ />
<step command=”KEY” value=”ENTER”>
<field name=”WBDWDZ”>080313</field>
<field name=”WBDWHZ”>1530</field>
<step command=”KEY” value=”F3″ />

This little script goes through and will update the delivery date and the time, it will also close the panel when finished. So, we are looking pretty good.

The next issue is that we need to make sure that we aren’t interrupted – so we are going to use Modal dialogs.

We need to be able to handle the user changing the settings for OIS301 aswell, we can automate that too. And then finally we need to push that all out to code.

What I have done is I’ve added a button called TestAutomation, and a couple of textboxes which I can entered in order numbers, dates and times to run some tests.

And finally I have converted my steps above to use the automation helper classes.

        private void btnTestAutomation_Click(object sender, RoutedEventArgs e)
            MFormsAutomation mfaAutomation = new MFormsAutomation();

            // run OIS301
            mfaAutomation.AddStep(ActionType.Run, "OIS301");
            // go to the settings panel
            mfaAutomation.AddStep(ActionType.Key, "F13");
            mfaAutomation.AddStep(ActionType.Key, "ENTER");
            // we want to make sure that we are going to the browse view, A-Entry doesn't work!
            mfaAutomation.AddField("WWSPIC", "B-Browse");
            // close the panel
            mfaAutomation.AddStep(ActionType.Key, "F3");

            // we are going to relaunch OIS301
            mfaAutomation.AddStep(ActionType.Run, "OIS301");
            mfaAutomation.AddStep(ActionType.Key, "ENTER");

            // set the order number
            mfaAutomation.AddField("W1OBKV", tbOrderNumber.Text);
            // set the line number
            mfaAutomation.AddField("W1PONR", "1");
            // set the line suffix
            mfaAutomation.AddField("W1POSX", "");
            // set the panel sequence
            mfaAutomation.AddField("WWPRSEQ", "E");
            mfaAutomation.AddStep(ActionType.Key, "ENTER");

            // do the option -> Change to edit the record
            mfaAutomation.AddStep(ActionType.ListOption, MNEProtocol.OptionChange);
            mfaAutomation.AddStep(ActionType.Key, "ENTER");
            // update the date
            mfaAutomation.AddField("WBDWDZ", tbNewDate.Text);
            // update the time
            mfaAutomation.AddField("WBDWHZ", tbNewTime.Text);
            mfaAutomation.AddStep(ActionType.Key, "ENTER");
            // exit the panel
            mfaAutomation.AddStep(ActionType.Key, "F3");
            // finally, launch it all
            DashboardTaskService.Current.LaunchTaskModal(new Task(mfaAutomation.ToUri()), new LaunchEventHandler(LaunchTaskModal_LaunchEventHandler), new RunnerStatusChangedEventHandler(LaunchTaskModal_RunnerStatusChangedEventHandler2));

So, I know now that I can automate the updating of the addresses. I can’t update the route if the route changes without resorting to nefarious methods such as using SQL to update the database directly. This is not something that I want to do but isn’t that important at the moment.

Those of you that haven’t dozed off will have noticed that there is another button that I have added that I haven’t spoken about. “Test MIWorker”

The Test MIWorker is a quick bit of code I threw together to test that I could retrieve the line number and suffix for each line against an order through the APIs, imparticular, OIS100MI::LstLine

We require the line number and suffix so we can update each orders lines.

        private void btnTestMIWorker_Click(object sender, RoutedEventArgs e)
            MIRecord mirRecord = new MIRecord();

            // set the company to 100
            mirRecord["CONO"] = "100";
            // set the order number
            mirRecord["ORNO"] = "0000092053";

            // call the API, and then being a good little boy, I'm not blocking the UI thread
            // - we will go to my callback function
            MIWorker.Run("OIS100MI", "LstLine", mirRecord, TestMIWorker_Completed); 

        private void TestMIWorker_Completed(MIResponse response)
            if (false == response.HasError)
                // a quick and dirty dumping of the records
                foreach (MIRecord mirCurrentRecord in response.Items)
                    // retrieve the line number
                    string strPONR = mirCurrentRecord.GetString("PONR");
                    // retrieve the line suffix
                    string strPOSX = mirCurrentRecord.GetString("POSX");

                    // just dump them to the console
                    System.Console.WriteLine("PONR = " + strPONR);
                    System.Console.WriteLine("POSX = " + strPOSX);
                MessageBox.Show(response.ErrorCode + " " + response.ErrorMessage + Environment.NewLine + response.Error.Message);

So, I have all the pieces I need to move forward on to the next stage – creating a cohesive solution which brings everything that I have covered together.

We will now look at bringing everything together and providing the user with feedback about what is happening while we are working and finally look at some methods to validate everything updated.

This entry was posted in Development, M3 / MoveX, SDK. Bookmark the permalink.

4 Responses to Smart Office SDK – First Project Part 4 – Searching for and Validating Update Methods

  1. Daniel Henningsver says:

    Very interesting. I have also looked at mformsautomation but I experice quite some problem with the error message “Failed to render panel” in Smart Office when running an mforms automation. Have you had any similar problem?

    • potatoit says:

      Hi Daniel,

      no I haven’t encountered any issues like that, but I haven’t used the automation beyond this particular project. I have however been caught out on a number of instances where I needed an extra enter keypress where I wasn’t expecting it.

      What mforms program are you trying to automate and what are you trying to do? Which version of LSO are you using?


  2. Pingback: Smart Office SDK | M3 ideas

  3. Salem says:

    I am trying to fun SQL quey within SDK form. I read the SDK documentation but didn’t found M3ip or severName. Are they simple ways to run get data using SQL without writing user and password in the connection string (any method will help).
    Thank you

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s