Archive for November, 2009

The Developer vs. The Administrator

Posted by Jason Huber on November 25, 2009
Administrator, Developer / No Comments

Meeting many of you at Insights and Summit we in training know that you wear many hats. Some of you own the business, install the application for your clients, customize the product and support it for 10+ years and more! Some of the people I meet work for a customer and they are the SalesLogix “guy” or “gal” in the company. We have a student this week that is taking a developer course and has no development experience, but is going to be the main “gal” at the company in a few weeks.

Let’s talk perspective

The many hats you wear mean you do different jobs, but in my experience with all of you I see two main types of people: Administrators and Developers. Why the disctinction? Perspective.

An Administrator likes to have things in order, memorize details and steps, reads the manual and expects things to work (or fail) as expected. Resolutions are documented, reasons are sounds and reproduce-able, and overall it is a very structured world.

A Developer on the other hand expects to figure it out each and every time an error occurs. Never is something going as planned nor will the same circumstances repeat themselves – why bother to document it.

Why does this matter?

Administrators doing development tend to have a hard time adjusting to this fluid development environment. Especially when it comes to .NET and the various opportunities we have to debug an application in AA, outside AA in event viewer etc. It is not cut and dry, each scenario is different on just about each machine. Developers love to figure it out – even if it takes all day.

Developers have a similar problem with administration tasks. There are rules you follow when administering a SalesLogix installation. Just like good comments in code you follow the Administration rules so that the next SalesLogix Administrator can make the assumptions that they always make — they have the installation memorized if your read the manual! Administrators do not have all day to figure it out! Production is down and it needs to be back up now!

Can’t we all just get a long

We can. In some cases we are fighting with ourselves or we are doing something (like not documenting) that will come back to haunt us in the future. Best practices are like gold to an Administrator and boring drivel to a programmer. I know you have some good stories to tell, so please do – in the comments.

Increase Your Selling Power with SalesLogix Campaigns

Posted by Kristin Lisson on November 23, 2009
End User / No Comments

We’ve mainly focused on using the sales features in SalesLogix and would like to expand our Marketing Department’s use of the database. Can you tell me a little bit more about campaigns?

SalesLogix marketing features include tools to design and perform outbound campaigns. Campaign tools allow you to target an audience of leads or contacts, manage stages and tasks, track responses, and analyze the budget and campaign success. Campaigns are a great way to increase your selling power!

Let’s look at how SalesLogix supports the following typical campaign process:

1. Decide what kind of marketing campaign you are going to conduct.

For direct mail, telemarketing, magazine or newspaper advertising, you’ll generally set up those campaigns in SalesLogix in the same manner. For an e-mail blast, however, you need to plan whether or not you want to integrate an e-mail marketing tool with SalesLogix.* Setting up integration with any number of third-party providers—SwiftPage, Empulse, and more—is easy, and it allows you to select your target list using SalesLogix and synchronize that data with a tool specifically designed to help you create richly formatted e-mail messages. After you schedule and send the message, tracking data is sent back to SalesLogix so you can view click-and-open data as well as measure campaign effectiveness in the Budget/Reports tab.

campaign-0001

*E-mail marketing integration is available with the SalesLogix LAN product only.

2. Enter the details of the campaign.

Entering campaign details into SalesLogix is easy. Define your message, call to action, lead sources, products featured, start and end dates, and the campaign manager. Also list a campaign status so other SalesLogix users know if you are in still the setup process or if you are ready to launch.

campaign-0002

3. Assign campaign stages and tasks.

There are often several people required to make a campaign run smoothly—for example, you might require artwork from your Graphic/Design department and product specifications from Product Development. To manage all of these tasks, SalesLogix allows you to organize campaigns with stages and tasks. After assigning different users tasks, you can export the entire list to Excel or you can manage open tasks in the Campaign List view. You can also enter anticipated cost or hours for each task so that after completion, you can measure the variance in your Budget/Reports tab.

campaign-0003

4. Filter a list of campaign targets.

Hey, you already have massive amounts of contact and lead data in SalesLogix; it only makes sense to use SalesLogix to filter targeted campaign lists! SalesLogix allows you to pick campaign targets using a variety of criteria—ranging from company, products owned, city, and so on.

campaign-0004

5. Launch the campaign.

When you are physically ready to launch the campaign, make sure to record the launch in SalesLogix. Launching the campaign allows SalesLogix to begin tracking information used in reports, budgets, and so on.
When a campaign is launched, campaign targets are assigned to the first stage of a campaign and their status is changed to “Launched.”

campaign-0005

6. Track incoming responses and create related opportunities.

Next to a dog perhaps, a response is a campaign manager’s best friend. SalesLogix makes it easy to track responses as they come in via phone, e-mail, in person, tradeshow, and so on. When you mark one of your targets as having responded, it updates the Budget/Reports tab to help measure campaign success. An even bigger victory to track is whether or not a response generated an opportunity or a sale. SalesLogix allows you to easily associate a new opportunity with a response, which also affects your Budget/Reports success.

campaign-0006

If you use e-mail marketing, automated response data generated from your marketing service provider is also updated in SalesLogix. You can even view which users opened the message, which users clicked on any links, and which users unsubscribed as a result of the message.

7. Analyze the campaign budget results to measure its effectiveness.

Having a way to measure campaign effectiveness is critical. SalesLogix provides a Budget/Reports tab that tracks Potential, Expected, Actual, and Variance for responses and opportunities. You can also generate more detailed reports using the SalesLogix Reports feature.

campaign-0007

Tags: , , , , , ,

Administrative Considerations for SalesLogix End Users

Posted by Kristin Lisson on November 18, 2009
End User / 1 Comment

The Sage SalesLogix Network Client is a powerful tool because your company can add its own customizations to better support your unique business rules and processes.

With a Sage SalesLogix Client implementation at your office, there’s always a companion installation of the SalesLogix Administrator application. This Administrator application runs as its own program, and it controls the interface—and even the data—that you see when you log on to the SalesLogix Client.

As you might expect, the actual person responsible for managing this SalesLogix Administrator application is referred to as your SalesLogix administrator. (Creative name, right?) The administrator’s most common tasks are setting up licenses, creating users and teams, and installing customization bundles/service packs. (Heavy-duty customizations, by the way, are created in a separate application called the SalesLogix Architect.)

As you work through the End User curriculum or consult the SalesLogix Help Files, you may see lots of references to your administrator. With so many options for configuration, it’s easy to get lost in the footnotes. This document provides a list of specific features controlled by your administrator that you might find useful in a discussion with your administrator during the early phases of your SalesLogix implementation.

Note:
As a user, you can configure some of your own options without having to rely on your Administrator; in fact, some settings are available in both the Client and Administrator applications. In the following table, if you see a * denoted next to an option, it indicates a setting that is available to both users and administrators. To find those settings in the Client, click Tools > Options and Tools > Client Options.

Download the Administrative Considerations Check List.

Tags: , , ,

Mashups in 7.5.2 — a few changes and debugging?

Posted by Jason Huber on November 16, 2009
Developer / No Comments

In preparation for Summit 09 (which by this time is over) I was working on my Mashup presentation. It is a neat example that simply pulls information from the account and uses that to search twitter and then outputs the result into both a sparkline and timeline formatted feed. This looks a lot like an upside down Y. Usually you get something that is a right-side up Y.
Mashups1

So what changed?

The change is really in the feed itself. Previously we needed to alias the fields in the SQL statement as they were passed in and out of the mashup items:

1
select a.AccountName from Accounts a where a.AccountId = :EntityId

Now you do not need to do the aliasing anymore:

1
select AccountName from Accounts  where AccountId = :EntityId

Also if you notice the EntityID is now EntityId. This is just a small change, but it certainly matters.

Is that it?

Yeah really it is. If you were to refer to AccountName later you do not need to alias it there either.

What about Debugging Mashups?

In this case I used FireFox and FireBug. It was nice to just open up FireFox and Firebug and simply see the mashup requests going by:

Mashups2

What does that give me? In this case, not much. I could have just copied the URL and pasted it into the browser and had about the same result, but at least Firebug saves me a step.

Making Quick Edits

We cover this particular thing really well in our classes, but you can edit the file quickly from the file system on the web server.

What you will get when you do this is something like this:

Mashups3

And editing it in notepad will allow you to see the markup that makes up the mashup. Change this one file and refresh your browser and you will see your changes. This makes debugging mashups a lot faster than waiting for another deploy.

Use the examples!

Use the examples that are contained within the folder already. Both are designed for timeline controls and output the correct format. For a sparkline the data needs to represented by a series of “d”s and that is it. Just take what you see and do what you can with it. Using the examples is a great way to learn — and come to class!

Tags: ,

SData helper functions — C# code to make SData consumption easier

Posted by Jason Huber on November 11, 2009
Developer / No Comments

What about the Client Libraries?

The first thing that comes to mind when you read the title is “What about the SData Client Libraries?” The easy answer? They are here, they will work with SP2 and will be your first choice when starting an SData project with .NET.

What we have here are a set of helper functions that may do two things: 1. Help you understand what needs to be done in code to work with SData (increase your understanding) and 2. provide an outline for converting this sort of thing to another language (such as JavaScript or Java).

GETting some SData

To GET started you need to pull some data from SalesLogix SData. This usually requires some sort of http request and then parsing the response. We do this in a few methods:

  1. Download the XML passing in the URI (http address of the resource)
  2. Get the <entry> from the feed
  3. Work with some values in the feed

Download the XML

_user = “Lee”
and
_password = “”

1
2
3
4
5
6
7
8
9
10
11
12
13
 private string DownloadXML(string sUrl)
        {
            System.Net.WebClient client = new System.Net.WebClient();
            client.Encoding = Encoding.UTF8;
            client.Headers.Add(System.Net.HttpRequestHeader.ContentType, "application/atom+xml");
            client.Credentials = new System.Net.NetworkCredential(_User, _Password);
 
            string result = client.DownloadString(sUrl);
            client.Dispose();
            client = null;
            return result.Substring(1);
 
        }

Get the entry from the feed

Remember that the SData feed is an ATOM feed. You usually want the entry node from this feed. So let’s get that and work with it. This step makes parsing the xml later a bit easier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private string GetEntryFromFeed(string xinput, string entry)
        {
            var doc = new XmlDocument();
            doc.LoadXml(xinput);
 
            System.Xml.XPath.XPathNavigator xmlNav = doc.DocumentElement.CreateNavigator();
            var manager = new XmlNamespaceManager(doc.NameTable);
            XmlNamespaceManagerAddNamespacesforslx(ref manager);
            //get the first entry node and put the feed node back on (now you have a feed entry)
 
            XPathNodeIterator nav = xmlNav.Select(entry, manager);
            nav.MoveNext();
            return nav.Current.InnerXml;
 
            nav = null;
            manager = null;
            doc = null;
 
 
 
        }

and the call to this function is:

1
GetEntryFromFeed(results, "//atom:entry")

Which leads us into the issue with namespaces. You have several of them in this atom feed and each must be defined. You can see I called a function to set these up for me:

1
XmlNamespaceManagerAddNamespacesforslx(ref manager);

And all it does is add all the namespaces for me:

1
2
3
4
5
6
7
8
9
 private void XmlNamespaceManagerAddNamespacesforslx(ref XmlNamespaceManager xnsm)
        {
            xnsm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            xnsm.AddNamespace("slx", "http://schemas.sage.com/dynamic/2007");
            xnsm.AddNamespace("sdata", "http://schemas.sage.com/sdata/2008/1");
            xnsm.AddNamespace("atom", "http://www.w3.org/2005/Atom");
            xnsm.AddNamespace("opensearch", "http://a9.com/-/spec/opensearch/1.1/");
            xnsm.AddNamespace("http", "http://schemas.sage.com/sdata/http/2008/1");
        }

Work with some values in the feed

Before I can work with the xml I need to get it into an XmlDocument:

1
2
            XmlDocument xmlTicket = new XmlDocument();
            xmlTicket.LoadXml("&lt;entry>" + GetEntryFromFeed(results, "//atom:entry") + "&lt;/entry>");

You can see that I re-add the <entry> node around the result from the function calls above.

The call to get a single value is here:

1
GetSingleValueFromxmldoc(xmldoc, "//slx:TicketNumber");

And what code is needed to get the value?

1
2
3
4
5
6
7
8
         private string GetSingleValueFromxmldoc(XmlDocument xdoc, string sNodeName)
        {
            var manager = new XmlNamespaceManager(xdoc.NameTable);
            XmlNamespaceManagerAddNamespacesforslx(ref manager);
 
            XmlNode xnode = xdoc.SelectSingleNode(sNodeName, manager);
            return  xnode.InnerText;
        }

So that is 4-5 simple helper functions for working with xml in C#. The same goes for JavaScript in FF. You do nearly the same operations. The major differences are that you do not need to specify the namespaces in any certain way:

xml.getElementsByTagName can be used and just pass in the actual node name.

Tags: , , ,

DataGrids and DataTables – simple example

Posted by Jason Huber on November 09, 2009
Developer / No Comments

We are using System.Data.DataTable in many examples and you will it a lot on the web in examples too. Here is a really quick primer on what is going on.

Visualize it

datagrid_datatable_excel
What a DataTable looks like to me is a simple excel spreadsheet. It has columns and rows. It is as simple as that. You build the DataTable by telling it what columns it should have and their type (int, string, etc). Then you add rows. Is this now how an Excel spreadsheet is built too? Name the columns and then enter data?

Build the table

First you need to build the actual table in memory. This would be the same as the spreadsheet with no data:

1
2
3
4
5
 DataTable myTable = new DataTable();
            myTable.Columns.Add("ID",typeof(int));
            myTable.Columns.Add("FName", typeof(string));
            myTable.Columns.Add("LName", typeof(string));
            myTable.Columns.Add("Address", typeof(string));

I have 4 fields, first one is an int, the rest are strings. You can then add rows. Isn’t this what we do in excel? It is about the same process.

Add some Data

Now we need to add some data. We can easily do this through the .rows collection:

1
2
3
4
 myTable.Rows.Add(1, "Jason", "Huber", "Phoenix, AZ");
            myTable.Rows.Add(2, "Randy", "Pausch", "-");
            myTable.Rows.Add(3, "Aldous", "Huxley", "-");
            myTable.Rows.Add(4, "Timothy", "Ferris", "San Fransisco, CA");

You have a few overloads for this and sometimes you will see code where they actually create a new row object, fill it up and then place it into the DataTable. Usually the above code is what I am able to use.

Now your DataTable looks the same as your excel spreadsheet (the one in your mind). How can we get it to display on the screen?

Binding the DataTable to the DataGrid

It isn’t a datagrid anymore and hasn’t been for sometime. It is a GridView. I simply dropped a GridView from the data section of the toolbox onto my form and left the name as is: dataGridView1.

Then we can go back to our code and bind to it. Keep in mind all the code I have posted so far is going into the page load and can be pasted in the order I have posted it.

1
dataGridView1.DataSource = myTable;

What do you end up with? A nice datagrid with your data. DataTables are pretty useful. We can sort and filter too. Makes a DataTable a nice format to get familiar with.
datagrid_datatable_Form

Tags: ,

Updating the UI or the Entity? Which one matters?

Posted by Jason Huber on November 03, 2009
Developer / No Comments

When I first started with Sage SalesLogix web version 7.2.2 I was really used to the “old web”. The web before web 2.0 was really what I programmed in. I had some experience with AJAX and a lot of experience with XML and JavaScript, but an Object-Relational Mapping Software? No. I was used to using Stored Procedures or inline SQL to update the database. Easy stuff like that.

Working with Entities

Now with nHibernate and our Entity Model we need to learn to talk to the Entities. Updating the User Interface is really secondary to getting the Entity updated. If I need to change a text field on a form and have it saved to the database I am really wanting to update the entity and then update the UI if needed.

The UI is what we go to first. We want to change the form and have the entity pick up all the form values and get saved. That is not how it works. Let’s take my simple example of a slxboolean field on account – UsesPayPal. I update the entity in Application Architect and made that property a YesNo type. I have built my entities and I have a new form called AccountPayPal. I tied a checkbox to that new property and added a button too.

Updating_the_ui_Web

The code

The code under the button is a Code Snippet Action Item. I have mentioned previously that this should be used as often as possible over the C# Snippet Action Items for various reasons.

The code I entered was:

1
2
3
4
5
6
7
public static void QFButton_OnClickStep1( IAccountPayPal form,  EventArgs args)
        {
            // TODO: Complete business rule implementation
			form.chkUsesPaypal.Checked = !form.chkUsesPaypal.Checked;
			Sage.Entity.Interfaces.IAccount myAccount = (Sage.Entity.Interfaces.IAccount)form.CurrentEntity;
			myAccount.UsesPaypal = form.chkUsesPaypal.Checked;
        }

What it is doing is first changing the UI. Again, I do not need to do this, but it makes the UI behave how the user expects it to. Also I can use the value of the checkbox against itself to make my code a bit more concise. Later (3 lines down) I will check the checkbox to set the actual value on the entity.

Second I am getting a variable which is equal to the current entity bound to the form. I have to declare an object of that type and then cast the form.CurrentEntity to that type. I can then use that variable to change the .UsesPaypal Property setting it equal to the Checked property of the checkbox. If your control is a textbox or the property is not a true/false type property this last line will not work for you as-is. This was just a simple example that I could mold for this need. You will need to cast the property to .ToString() it.

Where do we end up?

We end up editing the User Interface so that it behaves how the user expects it to behave. Then we do the real work of updating the entity itself. This is a slight change from the way I used to think of web applications back in the classic ASP days, but easy enough to get used to. The great thing is that the form which is passed into the method gives you really good control over the entity and the form elements. You are somewhat protected and get intellisense and all of that good stuff we expect from a good editor.

Tags: ,

SalesLogix Security — turning it off

Posted by Jason Huber on November 02, 2009
Administrator, Developer / No Comments

I recently received an email from a customer who was not using SalesLogix Security in their implementation. No Teams or anything like that at all. Just users who can see all accounts and all contacts in the system. They were also looking at some of the performance enhancements our PSG team has published and wanted to go one step further to remove security altogether.

What does “removing security altogether” mean? Well it really just means not joining on SECCODEID. Out of the box SalesLogix uses this field to maintain rights on the various objects within the product. If you are not using security this is at least an extra join on many select statements. Just unnecessary in this case.

So how do we “turn it off”?

In the SLXPROVIDERPLUGIN table you can find the row where coclass = SlxSecurity and set enabled = F.
slxproviderplugin_speed_table
Restart your client application and no more SECCODEID. You can check this out using SLX Profiler. If you perform this check on the evaluation database you are likely to see your times increase! Why? Because more rows are now returned. The query may be faster, but more rows are coming back from most queries, so they will take longer. If you are working in a database with no security already this may not be the case.

You probably want to test this out a bit first. What I suggest is using profiler and entering a filter:
slxproviderplugin_speed_profiler1
I have had good luck with: executedsql like ‘(?i)seccodeid’

What about custom security?

In our Lan Developer course we cover implementing your own security wrapper and it works really well. Does it still work if you turn off the default security? Yes it does. Just like the History restrictions and activity provider plug-ins, your custom plug-in will continue to work as expected. These plugins build on each other, so you can have as many or as few as you like.

Seccodeid is not eliminated altogether however. It is still part of many select statements and will still be found if you turn off security and perform a filter in SLX Profiler. This isn’t something we can change and should have little effect on performance. We are really concerned with the extra joins in our SQL, not extra fields.

What other performance implications are there?

Well this is one of many performance enhancement that are suggested to try in your environment. Obviously this will not work for everyone and neither will many of the other suggestions. The purpose is to expose as many enhancements that can be tested in the variety of environments where SalesLogix can be installed. Test, test and then test some more. Then implement slowly into production. Keep making backups and always have a fall back plan.

Tags: , , ,