We’re in the process of going from MoveX V12 Java, SP16 fix pack6, Foundation 7.1, Apps 5.2 to M3 V14, or 10.1 and 10.1 offers us a lot of opportunities through Smart Office and WebServices.

One of the issues that caused a lot of grief has been the APIs in MoveX V12 are very weak, they often get 60% of the way to achieving a goal but then don’t have the other core 40% of functionality there so you end up having to take a hybrid approach of direct SQL reads and APIs and using MoveX Explorer. Or worse still, you have a situation where the API functionality doesn’t honour all of the rules that the client does so you end up with inconsistent behaviour.

As most of you have no-doubt experienced, ERP solutions though great, often leave these little holes or gaps that your organisation needs to fill – this can’t be solved with MoveX alone. One of these gaps for us was EFT processing, in short creating a file of payments to suppliers that we upload to our bank for electronic payment.

The Lawson solution was to use MeC, and it is a horrible, horrible solution. MeC is over complicated and can get so severely screwed up with timing issues when it comes to payments that you have to adjust your process to work around the shortcomings – increasing workload and increasing the chances that your Accounts Payable staff can make a mistake, that’s before we get in to the arcane setup you need to go through and the consulting in-experience in this end of the world. Don’t get me wrong, I’m sure MeC has its place, but for us, it was like using an industrial power drill to hammer in a tac.

So for us I wrote a little .Net application that did away with the MeC side of the equation, it would use the APIs CRS692MI and APS130MI along with several SQL statements to extract a payment proposal, the payment proposals items and the bank account details and finally handle the deletion of the payment proposal.

In the upgrade it looks like something has changed around the functionality in APS130MI and it proposal deletion function which prevents it from working correctly (takes the proposal to status 4 indefinitely, an issue we are logging with Lawson). Which prompted me to consider, instead of using an external application, why not just create a jscript within Smart Office – the user will just highlight the proposal and click on the “Generate EFT” button and it will spit out a file which can then be uploaded – no more nonsense with APIs, additional user logins, SQL requirements and additional programs.

A jscript for generating the EFTs? Conceptually, very straight forward, the EFT program really consists of several loops and a function that spits out a file in the right format, can’t really get much easier. However, it requires usage of classes, properties, may use a window to display information and need to capture some of the events from the new window; things that I haven’t had any experience with in a jscript world.

So, I decided that I would clean up my earlier code around reflection, have it so it is displayed in a ListView (so I can use binding to make life easier) on a newly opened Window and set it up so you could select a property and then open a new window and show the selected objects info to give me a better idea of design for the EFTs.

Defining Classes

Well, this part is pretty simple, when we use the mforms://jscript editor and go New it creates the package and the class for us, so we have a framework to work with. But can we just define another class within the one package? Can we include a class within a class, what happens when we do that? Yes, yes and not a lot J

To start with I created a very basic class, it has a couple of variables and a constructor. It is the class that we will be using to store the information about each piece of information we find when we do a discovery on an object.

As you can see, not a lot to it, for the sake of experimentation and I do like type safety, I’ve set the data type of the variables, I defined a constructor so we could easily create and initialise the object in a single hit. After spending a lot of time in a type safe world and my unconditional love of properties I wondered if properties were supported within jscript, this little project was going to need properties that I could bind the ListView columns too.

Here we set our variables to private, so no functions outside of this class should be able to change their values. The only way for the values to change is when you construct the object, and this will suit our purposes quite nicely.

The new parts that we have are is:

function get Name() : String

Quite simply, it is defining a function which is presented as a property, using the keyword get or set allows you to get or set a value as if it were a property. Name() is the name of the property, and : String says that this is going to return a String.

return this.pri_Name;

Will then return the value stored in pri_Name

Given we are effectively replicating many of the values in the MemberInfo class that we use to populate this object, we could have probably looked at inheritance, but that’s for another day to look in to.

Ok, so now we have a class which will store our values and supports properties so we can bind our columns to it.

Assemblies

In order to use reflection and some of the methods that I use we need to include other assemblies.

Most of these are already defined when you create a new jscript within the Smart Office editor.

Incidently, if you want to take a look at the assembles that Lawson provide, then you can use the Visual Studio Object Browser. The filename of the assemblies typically is the name of the Assembly with a .dll appended to the end (eg. Mango.UI.Core.dll), these are stored in the directory that the ClickOnce deployment dropped Smart Office in to, usually <user profile>\AppData\Local\2.0\<random name>\<random name>\<crytic GUID>\, basically I do a search in the AppData directory for Mango and it will show up the assemblies, in my case:

Events

Now events caused me a lot of problems within this little project, you look at the Lawson provided examples and it makes event handling look so much more simpler than in the big boy programming languages J

Events cannot be created within jscript L, however you can subscribe to existing events. You need to find out what the event is called for an object and then call <object>.add_<eventname>(<event handling function>) and a call will need to be made later to unsubscribe from the event, this follows a similar format <object>.remove_<eventname>(<event handling function>)

Turns out that they can be very challenging, especially within Smart Office. I found that timing can be everything between hoses your Smart Office instance and it working flawlessly, that you have be pay very special attention to cleaning up resources and getting handlers of events arguments 100% correct – even then, I couldn’t for the life of my get the MouseDoubleClick event to fire in my ListView so resorted to SelectionChanged events.

In my situation I ended up adding event handlers that would listen for the closing of our window and the loaded event. Within the loaded event I would then add a handler to listen for SelectionChanged events against the ListView. Because this was such a problematic area I ended up leaving the event registration within the loaded event.

public function OnReflectionWindowLoaded(sender: Object, e: RoutedEventArgs)
{
try
{
// ensure that we have a ListView object to attach to
if(null != wndReflectionWindow.lvListView)
{
// do the actual attach
wndReflectionWindow.lvListView.add_SelectionChanged(OnSelectionChange);
// if no exception was generated, then set a
// flag so we know we did infact attach and will
// need to eventually dispose of the attachment
wndReflectionWindow.bListViewMouseDoubleClickAdded = true;
}
}
catch(ex)
{
MessageBox.Show("Exception adding MouseDoubleClick to ListView: " + ex.Message + Environment.NewLine + ex.StackTrace);
}
}
public function OnSelectionChange(sender: Object, e: SelectionChangedEventArgs)
{
// do something really fancy
}

So when our Windows Loaded event is fired (basically once everything has been initialised), we attach a handler to our ListView looking for any SelectionChanged events, if there is one then the OnSelectionChange function will be called. It is absolutely critical to get the type correct for the EventArgs, odd things happen within Smart Office ranging from cryptic compile errors to bizzare crashes if you don’t.

It helps to refer to the library at http://msdn.microsoft.com has a lot of information on events and the args types, unfortunately the jscript examples are almost non-existant.

The Code

The moment you’ve been waiting for, the code. I was testing this against BUS100, so if you want to test this directly in your TEST environment, in Smart Office run BUS100 and then load the jscript editor and paste in the code. I’ve added a lot of comments in here to explain what is happening. In my example I use the Lawson ListView as the object I will examine.

There is a lot of ways that this could be expanded. I’ve created a ReflectionWindow class to hold some common values and in the knowledge that one day I will add code to allow us to open multiple windows at a time and recurse through objects.

If you want to get information on property from the first opened ListView, then hold down the Alt key and then select the property you want to inspect. A new window will open (oddly UNDER the main listview window).

Also NOTE that when-ever I selected any of the Lawson objects the script would get in to a mess, not sure why but it basically meant a restart of Smart Office to get things running again.

And that’s it. Given the code above runs through almost all of the concepts I need with the EFTs (except for writing to files and web-services), then I hope to convert my EFT code in to jscript over the next couple of weekends and post it here.

Update 20101122 As it turns out, the priority of the source code has been reduced as Lawson provided a fix before we went live on 10.1, see fix JT-185102

Smart Client / Office are truly great products (which is part of the reason why I’ve been tinkering with reflection) and I think that the information needs to be there for people to take advantage of – if even to know that something is possible – or they aren’t the only ones to stumble across something that just don’t quite seem right 🙂

I believe that you can directly call the APIs from the jscript, that will of-course mean that you have to distribute the mvxAPI toolset to each computer that is going to run the jscript in question. IIRC the mvxsock*.dll is a COM object and you can use something similar to what I did with getting Excel access in my other blog postings – so something like:
var mvxSocket = new ActiveXObject();

I’d tend to recommend that you wrap the API in a webservice and call the webservice. While we’re on the subject, be aware that the API field positions can move between versions of M3, check out my posting “APIs – don’t forget to read the fine print!”