Sage SalesLogix Real time Sync Issue

2 windows service components handle message synchronization for the Sage SalesLogix Mobile platform. The connector and Real-Time sync engine handle the synchronization process in different ways. Firstly the synchronization data is created and passed through the connector for all synchronization scenarios. The real-time engine is responsible for detecting and notifying a users device that new data (that has been identified in a watch) exists in the main database. If we look as the connector as the right hand, and the real-time sync as the left hand there is a time were the right does not know what the left is doing. This occurs specifically when you initiate the full sync on the device (initial load) and real-time is enabled. Since real-time is is initiated and the full sync has started and can take some tome to process it is possible that the real-time can disrupt the load process. This happens because the when a real-time sync occurs it looks into the queue to see if another sync is occurring and cancels it with the assumption that the current state of the database is newer and the changes will rollup, with the hope of reducing bandwidth requirements. In most scenarios this would be a good thing except for the initial load where having the load canceled is not such a good thing.

To get around this issue ensure that your admin does not turn on real-time sync for a given user until their initial load is completed. This will allow the connector to work undisturbed and get the load data onto the users device.

– mark

I’ve seen the ‘Dynamic’ Light

Hey did you hear, VS 2010 is released and production worthy. We at BITtelligent did not wait long to start to put it into our daily work flow and I have to say I am quite impressed and happy that we did. In in the IDE side, but more so in the C#4 language improvements.

We are working on a large project with a different complexity challenges. The project is loosely based on a current implementation that is in production. That being said there are instances of where system settings are retrieved from the database to determine the process flow.

so code exists such as

if (cbool(container.settings.LocateValueFromSetting(“aaaa aaaa aaaa”)) = true

Now for me the intent is lost in the complexity of the check. This means more comments and a harder time for someone to grok my code.

Its quite possible to wrap the settings type with either proxy or add extension methods to allow for a better maintainability.

code such as;

ProxyClass proxy = new ProxyClass(settings);
if (proxy.ShouldExecuteSomeCode())
{

}
- or - 
public static bool ShouldExecuteSomeCode(this SpecialDataSet settings)
{
   return Convert.ToBoolean(settings.FindSettingBySettingName("Should Execute Some Code"));
}

Now this code needs to be repeated for each and every setting value and that seems to me to be a pretty heavy handed way of coding up the solution.

Enter dynamic.

Since I was looking for the most efficient and manageable way to provide settings access I moved into using a dictionary<string, object> as my local storage mechanism.  and for explanation purposes the following code is included;

 public class DynamicSettingClass : DynamicObject 
    {
        Dictionary<string, object> _values;

        /// <summary>
        /// Initializes a new instance of the DynamicSettingClass class.
        /// </summary>
        /// <param name="values"></param>
        public DynamicSettingClass(Dictionary<string, object> values)
        {
            _values = values;
        }

        /// <summary>
        /// Initializes a new instance of the DynamicSettingClass class.
        /// </summary>
        public DynamicSettingClass()
        {
            _values = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);    
        }

        public void AddSettingValue(string key, object value)
        {
            if (_values.ContainsKey(key))
                _values[key] = value;
            else
                _values.Add(key, value);

        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            string keyName = FormattedName(binder.Name);
            if (_values.ContainsKey(keyName))
            {
                result = _values[keyName];
                return true;
            }

            return base.TryGetMember(binder, out result);
        }

        private static string FormattedName(string name)
        {
            if (name.IndexOf('_') > 0) name = name.Replace('_', ' ');
            return name;
        }

    }

What this class enables is the ability to address each of the setting values as a property of our object instead of as a collection item.

Now the secret sauce is in the TryGetMember, and Formatted name. Within the TryGetMember we are provided important information in the binder object but for our sample the most important is the name property. From it we can derrive the targeted setting we are looking for. I add a little preprocessing to the key value as settings values can contain spaces, so a little token replace is required. The final outcome is that I can use this utility class to enhance the readability of my code and reduce the amount of lines to write to get the experience for all of my setting requirements.

so to now access the setting using the following code I would do the following;

dynamic simpleSettings = new DynamicSettingClass();
simpleSettings.AddSetting("Should_Execute_Some_Code", true);

if (simpleSettings.Should_Execute_Some_Code)
{
}

This seems to be a simpler syntax for accessing my settings list but really having to call the AddSetting method seems incomplete. So we can finally and a little more ‘magic’ to our settings class;

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        string keyName = FormattedName(binder.Name);
        AddSettingValue(keyName, value);
        return true;
    }

With this little snippet the round tripping is now possible with our Dynamic property example;

simpleSettings.Should_Execute_Some_Code = true;

if (simpleSettings.Should_Execute_Some_Code)
{
}

So this completes this post. I hope it helps you out in seeing the power of the DynamicObject’s power.

DevTeach Initial Thoughts

I have had in the past a reservation in attending conferences. In general I set lofty expectations and feel somewhat let down when they do not come to fruition. If I am to put my life on pause, leave my family and put my customers on hold for a week, with an investment cost greater then just the fee, transportation or hotel, I believe the content that is presented should be not some re-hash of what I can get on the web after 5 minutes of Goggling or Binging (is that the term).

I decided to cut away from this hesitation and this year attend the DevTeach conference (It is still on). I had heard good things, and the speakers were recognizable and notable. It was also a bonus as it was quite literally 30 minutes down the highway from my house. I felt so compelled initially that I even booked a room at the delta where I believe the conference was taking place so that I could spend some afterhours time with some of the other attendees enjoying a frosty beverage.

Just after arrival I was able to sit down and spend the balance of the evening with Peter Richie, Rob Windsor, Mario Cardinal, K. Scott Allen, Donald Belcham, Kelly Cassidy, Erik Renaud,  and Rob Daigneau. A great bunch of guys and they all seem passionate about their Tech.

After a very lousy night of sleep, I decided to abandon my decision to stay in the hotel for the duration of the conference and booked out during lunch, actually before, I wanted to get into a session on architecture put on by Michael Stiefel but was unable.

The first day for me was somewhat of a let down and I think it was due to the fact that I started off by going to some of the tooling session (language C#, V.net, Keynote, and VS for Architects). Except for a few notables these sessions for me were nothing more then marketing and a rehash of pre-canned content that has been available on the web, not much substance, and definitely no wow factor or call to action.

Both of the presenters in those sessions are very likable, and I believe great people for our community as a whole. I just felt that after the commitment that the attendees the payback was minimal. That being said I like where Sharepoint development is going and the slight overview of how to create sharepoint customizations in 2010 was good.

I am getting ready to head back to the conference for Day 2 and hope that If I change my ways (no more ms tooling sessions) the content will be engaging and provide the value I so really seek. The saving grace so far is the promise that all the sessions are being recorded, giving me the chance to view the ones that I cannot attend, at home, in the office at a time when they are not disruptive to my business practice.

Time for a coffee and a car ride,

2010 – The year for debt reduction

I have been on a course of reducing debt over the last few years. More purchases using cash, paying most bills as quick as possible. But like most Canadians (Americans as well) I carry some credit card debt. My interest rate for my cards was quite reasonable so I had gotten somewhat use to using them to make mostly online purchases. Over the last little while my rate had jumped several percentage points. I was upset, however I decided that I could live with an increase for now. However today on my latest credit card statement the rate was bound to jump another 2%. I can absolutely understand when the cost of debt is high or that the account is in poor standing that interest rates would reflect those realities, however neither is the case here since the current overnight lending rate in Canada is 1/4 percent and my credit card account is always been in good standing. I am not going to speculate on why this is happening, when I spoke to the representative on the phone I was told that lots of accounts were going up and that the actual base rate was almost 20%. I have decided out of principal that I can no longer deal with the vendor and be cancelling my credit card (paying off the remaining balance). After this we will be down to one household card, just enough for those emergency requirements/needs. I suspect I am one of the fortunate ones that can afford to pay off and close out an account but I wonder how many others will do the same when faced with this reality.

Read a book – Beginning BlackBerry Development

Beginning BlackBerry Development is a Light read at 238 pages. However there are enough golden nuggets of information to make it well worthwhile picking up this book. Remembering back to the days when I started BlackBerry development there was a complete lack of documentation with exception to the SDK guides to help the novice navigate the in and out’s of mobile development. I could imagine that I would have spent less time banging my head against the wall if I had a guide that would explain in simple terms the fundamentals of developing of with the platform. The book takes a basic approach and covers many of the topics required to get up and running and provides some insight into the 2 major development platforms for BlackBerry development, the JDE and Eclipse. I highly recommend this book for anyone getting into BlackBerry development and it is well worth the cover price in the time it will save in ramping up.

– Mark

It was just working …. What the hell

This is going to be short post on BlackBerry mobile development, specifically SalesLogix Mobile BlackBerry development. A current customer requirement called for the need of a multi-select pick list control. This control would allow the selection of 0,1 or many values from a pre-determined list. The stock pick list control provided in the platform does not support very rich scenarios like this so I was forced to create my own control. Its not that big of a deal, create a derived field control add a layout manager and host the controls you want to display. I have made good headway this weekend on the control with it generally working the way I expected until I decided to add the initial setting  of the selected items code. For this code we take the comma separated list of values and split it into each of the selected items, when finding a match, check that item as selected. So happily I wrote the code in eclipse and then moved it over to Sage Mobile Application Architect.  (I like and use eclipse for heavy java code development tasks). So when I compiled and deployed the client system I was quite surprised that I could not start the mobile application at all. There was no error, no visible indication that I had royally messed up, or that the customizations did not take. Nothing. So I went back to the code that I wrote and started to systematically comment/uncomment until i could find why the client was not starting up. Finally I hit pay-dirt and to my surprise the following line was causing the application to not start;

String[] values = selectedValues.Split(“,”);

What? I mean string splitting, it has to be there. Its such a basic function and eclipse tell me it exists through the dot prompt functionality. Digging into the BlackBerry API documentation it seems that this method really does not exist. Bah. So of course I roll my own custom split method and it works as expected.

Lesson: If the application will not start at all look at your customized code and ensure that you are not using some java API that is not supported on the mobile platform

SalesLogix 7.5.2

Now that SalesLogix 7.5.2 has officially released I wanted to revisit my decision to avoid ‘Code Snippet Actions’. I have been traditionally been using the Code snippets (Obsolete) actions in the past due to issues that I was having with the new form interface based actions. So for the last little while on several of the projects I have been working a specifically decided to to write all my UI event handlers using the form based actions. I have to say that I am very pleased in the stability that 7.5.2 introduced. It is a great step in the right direction. For the simplest UI based customizations it seems like a practical choice and it will be within my recommendations moving forward.

Now, even though it looks as if the code issues of working with Code Snippet actions have been resolved there is still a way to go until it is a very efficient way to develop advanced UI functionality. I want to cite several items that still need to be addressed.

1. Views that are generated and then translated into custom smart parts will fail to work. A form based interface is generated based on all of the designer forms in AA. Once a form is unbound from AA (made custom and moved into support files) the interface is no longer generated and your snippet methods will fail.

2. Accessing any non-interface defined properties or methods means casting to a specific control type. This kind of code is much easier to resolve in Visual Studio.

3. Common classes, shared methods are not first class citizens. If you want to create utility methods that are shared for all of your rules (UI/Business) you either have to create an external assembly and reference it or create an empty handler and add code after the closing } for the class definition that will be globally visible.

4. Though the platform is now based on 3.5 framework the CodeSnippets are defined as a 2.0 project so it may only be possible to have some of the new .net 3.5 goodness in a external assembly at this time. (I want to confirm this and see if there is a code gen script that can be updated)

One of the targets for 7.5.2 was increased performance. In this regard I have to say I am very happy, all around it seems snappier and more responsive.

It really looks as if this release is definitely moving the platform forward.

SalesLogix Quick Form Issue

I am working on a customization for a client and while making some changes to the Ticket Detail quick form and compiling I was getting a velocity exception as pictured here

I had been adding controls, and a new form load action when I got this issue so my first suspect was around the load action given the description. I systematically removed the script, and all of the newly added controls. To my dismay the exception continued to occur.  I then copied a fresh version of the TicketDetails smartpart/resx file back into the model and refreshed the project and the error went away.

It was then when I was re-cleaning the smart part when I found out what had happened. You see there is a contract lookup on the detail smart part. For this customization I had to remove it as it was not needed. When I removed it I was unaware that there was a reference to the control in a load action validation method. Since this reference still existed NVelocity could not resolve to the control hence the exception (though the error is not that descriptive). Once I removed the reference I was then able to recompile again.

So the Rule is: If you are removing a control from a smart part, ensure that there are no validation/property set actions referencing the control or you will see the above error.

MySlx, Do Overs and Next steps

Every time I start blogging again after a extended period away I mention that I will be working harder to create more posts. Surprisingly, or not so, I find it hard to find time to blog in a consistent manner. Mostly due to the fact that I am finding my day to day development efforts to be quite busy. That being said blogging and community is very important to me.

From time to time, I find that I would love to have days that would be considered a do-over. Nothing works as expected and the simplest work items are very difficult to effort. It could be environmental, lack of tooling, architecture or the product does not perform or is not at a place where it should be. These days can be tough for the most experienced of us as well as the new developer coming in trying to understand all of the underlying technologies. Yesterday was such a day, though the day was painful, there has been others and there will be more, ultimately I was able to move the product forward and solve some immediate customer pains.

It is unfortunate that these days exist, but they are a nature of the beast. We are working on complex systems with a myriad of technologies that are merged together to create some cohesive package. I think we understand this and I am fortunate that I have some very excellent customers, many of which I count as friends after many years of working together. What I am still struggling with is occasionally  the minimizing of the effort that it may take to get a development job done. It still gets me when someone, outside of the development fray can estimate an effort at 20-30% actual effort not bearing in mind all of the work items that need to be accomplished. Fortunately when these come along I do not have to engage in them as the risk is too high.

I count myself fortunate in that I have a geographically diverse customer base. I have clients in the USA, Canada, UK, and Germany. It has allowed me for the most part to ride out the difficulties in the economy. Somewhere in the next few weeks I am scheduled to head over to UK with a mid week hop to Denmark. It will be good to see parts of the world that I have yet to have been (its also nicer to get paid to do so).

SalesLogix 7.5.2 MySlx Types

SalesLogix 7.5.2 is due to be released soon and one of the new features is a simplification of some of the complexities of the platform. Note at time of writing MySlx Api components are in pre-release version and could have some changes by RTM.

So in a nutshell MySlx is start of wrapping some of the platform complexities into a set of cohesive, easily discoverable types. In its first release there are 3 types available for access as follows

  1. MySlx.Security
  2. MySlx.MainView
  3. MySlx.Data

Access to these types are available by default in the C# code snippets and full code complete support is provided.

Now here is an example of the Data type and a helper method to get back a list of ComponentView objects that can be directly bound to a grid. This allows for easier translation of current LAN client code to be consumed in the web client.

public static void GetContactThatStartWithA(IAccount account, out IList list)
{
    list = MySlx.Data.GetList(
                 "Select LastName, FirstName from Contact", 
                 new object[] { "LastName", "FirstName" });
}

Hopefully in the near future I can blog about each of the types and the methods that they contain.

Until then

– Mark

How fast can your car go

0-60, is a metric used to determine how long it takes a car to get to the top speed. The better the car is tuned the the lower the time to reach 60 mph. I was wondering on the weekend if this metric could be used in software development or more accordingly in the usage pattern of a company implementing a solution. Instead of 0 to 60 mph, why not 0-60% efficiency using the CRM, or EPR or some other software. So how long will it take your team to get 60, or 80 or even 100% value from your chosen software package. I suspect 100% is not a realistic target, but is 80% and if it is, what does it take to get there.

Talking with a business partner about the use of company internal developers vs. external BP based SalesLogix developers I wondered how long it would take for the internal developers, the ones that work for the end customer, to become 60% efficient at creating the customizations needed for the business to succeed. Also given the current economic climate where the internal developers are asked to do more in their already busy workday, how much of their focus would be on learning the technologies. These constraints can slow down the ability to reach that 60% efficient goal dramatically.

Couple the friction of getting the solution completed internally (technology, resources, capability) with the need for the business to get the solution in their hands, the initial perceived savings of in house development may actually be out of grasp. With a car, you can tweak and tune, and if needed be change the exhaust, tires, and even the engine the same cannot be said with a developer. When there is a business running on the software or solution it can better to couple with a partner, or developer who already has a tuned engine to aid in winning the race.