Quantcast
Channel: Customer FX
Viewing all 981 articles
Browse latest View live

Adding Filters to the Lookup Control at Runtime in the Infor CRM (formerly Saleslogix) Web Client

$
0
0

To add a new Lookup Pre-filter you can add code such as this on a quick form:


LookupPreFilter preFilter = new LookupPreFilter { PropertyName = "Type", OperatorCode = "=", FilterValue = "Customer", PropertyType = "System.String" };   
myControl.LookupPreFilters.Add(preFilter);   


Bug with Binding a Picklist Control in the Infor CRM (formerly Saleslogix) Web Client v8.1 Core Update 3b

$
0
0

I just recently discovered a bug when using a picklist control with the  StorageMode set to "ID".  If you are trying to preset a value on the form load, you would normally bind the underlying entity property that the control is bound to.  That works fine for picklists set to StorageMode=Text but for the ID mode it does not display a value.  Instead you also need to populate the web control's PickListValue property as well.  That forces the data to properly show

So a code snippet might look like this

Sage.Entity.Interfaces.ITicket t = this.BindingSource.Current as Sage.Entity.Interfaces.ITicket;

t.StatusCode = "Some picklist ID";

MyPicklistControl.PickListValue = "Some picklist ID"

Index of Posts for Starting with Infor CRM (Saleslogix) Development

$
0
0

The blogs on customerfx.com go all the way back to 2003. There's years and years worth of information that we've accumulated and shared. Since the beginning of the Infor CRM (Saleslogix) web client, we've been posting and sharing what we've learned ever since. However, if you're just starting with developing & customizing the web client, it might be hard to know what to start reading. This post will contain an index of posts that would be a good place to start when getting started working with the web client.

Accessing User Information & Current User
Programatically Looking Up Users
Determining if a User is a Member of a Team
Accessing User & Security Properties


Entity Factory & Entities
Using the EntityFactory to Retrieve Entity Objects
Finding the Current Parent Record ID
Adding Child Records Using the Entity Model


Queries, Repositories, & SQL
Querying Data Using Repositories & The SQL Equivalents
Returning a Distinct Result Set Using a Repository
Using a Repository and Criteria When You Have 3 "OR" Conditions
Returning the Sum of Fields Using Repositories
Running a SQL Update Statement
Retrieving the Underlying Database Information


Business Rules & Entity Events
Using an External Assembly for Entity Events and Business Rules
Wiring Up an Entity Event to an External Assembly
Creating a Business Rule to Return a List of Objects
Binding a Grid to a List Returning Business Rule
Creating an Account Business Rule to Return the Primary Contact


Forms & UI
A Step-by-Step to Adding a New Form for a New Custom Entity


Controls - Lookups
Adding a Parent Lookup to the Account Details Form
The Saleslogix Web Lookup Control
The Saleslogix Web Lookup Control Part 2
Limiting a Product Lookup to Current Account Product Records
Dynamically Restricting Lookup Controls Using the SeedProperty
Populating Both an ID and a Text Field With Lookup Results
How to Invoke a Web Lookup Control's Popup Event
The User Lookup Control & Defining Which Users Are Shown


Controls - Picklists
Utilizing the Picklist Assembly to Get Picklist Details
Working With Picklists


Controls - DataGrids
Filtering a Datagrid at Runtime
Setting the Default Sort for a Datagrid
Custom Format Columns in Datagrids


Security & Roles
Programatically Using Security Roles & Secured Actions
Accessing a User's Secured Actions to Determine Functionality


Groups
Programatically Creating a Lookup Group for a Specific Entity


Customer Portal
Getting the Contact for the Currently Logged in Customer Portal User


Bundling & Packaging Customizations
Installing a Web Bundle
Packaging Your Customizations (Video Training Session)
Delivering Data & Schema in Bundles
 

Are there other posts you think are helpful when getting started with Infor CRM (Saleslogix) Web Development? Add them to the comments.

Did You Miss The Infor CRM (Saleslogix) Performance Tool Webinar?

$
0
0
Watch the recording instead! If you missed last month's webinar where we explored the Infor CRM (Saleslogix) Performance Tool you now have the chance to view the recording:...(read more)

Working with the ClientEntityContext Service in the Infor CRM (formerly Saleslogix) Web Client

$
0
0

 In a previous post I talked about how to use the ClientEntityContext service to retrieve the current entity Id in client side javascript.  I wanted to expand upon that to detail the other options available to be retrieved by that service.

The properties that are accessible are:

  • EnitityId= the current record's Id.
  • Description=the defined String Expression for the Entity
  • EntityType = The Sage.Entity.Interfaces implementation name of the Entity.
  • EntityTableName = The underlying SQL table name the entity is bound to.

And here is a sample of accessing these in code. This sample is assuming being on a ticket.

var contextSvc = Sage.Services.getService('ClientEntityContext');
var context = contextSvc.getContext();
var strEntityId = context.EntityId; //Returns the Current Ticket Id
var strEntityDesc = context.Description; //Returns the Entity's String Expression, i.e. Ticket Number
var strEntityType = context.EntityType; //returns "Sage.Entity.Interfaces.ITicket"
var strEntityTable = context.EntityTableName; //returns "TICKET"


 

First Look: Infor CRM Update 05 and the Beautiful New User Interface

$
0
0
The soon to be released Infor CRM Update 05 (Core and Model) is one many of you have been eagerly awaiting, most likely because with this release you will see a completely revamped and beautiful user interface when you login to the v8.1 Web client. But Infor didn't stop the beautification at the Web client, they started working on the v3.2 Mobile client as well. Join us this month for a tour of both the Web and Mobile clients as we look at: ...(read more)

Infor CRM Summary Report

$
0
0
I had a user ask me what is the best way to figure out database statistics: 1. How many records are in my database? 2. What is the version of Infor CRM that I am running? 3. What Licenses do I own for Infro CRM? ...(read more)

Infor CRM (formerly Saleslogix) Web Client - How Time Zones Work

$
0
0

The Infor CRM web client utilizes  a couple of methods to determine and then present what timezones are available to be selected in the web client.

 

The first thing that happens, in code on the base.master page is a method LoginName_load runs.

Using the Sage.Platform.dll, in the Sage.Platform.TimeZone class the current user's timezone is retrieved.  This is stored in the USERINFO.TIMEZONE field.  This value matches the time zone name from the registry.

This value is then compared to the timezone of the current computer, also retrieved via the Sage.Platform.dll

If the 2 values dont match, then the users timezone is changed to the first timezone on the computer with a matching UTC offset. This is saved back to the USERINFO.TIMEZONE field.

This all happens as the page loads.

Finally,

In the Sage.Platform.dll the local registry is used to determine the time zones available.  By looking in this location: local machine\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\, the various keys are read.  This is serialized into a feed that is called through the slxdata handler at this address:

http://localhost:3333/slxclient/slxdata.ashx/slx/crm/-/timezones/p

With this list, the client compares the offset of the timezone now stored in the USERINFO.TIMEZONE field and using the slxdata handler, creates a list of all timezones on the computer with a matching UTC offset.   These are the timezones that are presented to the user when they attempt to change the timezone:

 

This list construction logic is contained in the massive minified Sage.js client side library.


First Impressions of Infor CRM update 05

$
0
0
I was able to get the new software loaded in my standard demo system today and my first impressions are: it looks very clean and modern, I like it a lot. What I was not prepared for is how much faster it is at navigating around. I don't know what they did specifically but, the results are incredible. At times, I found myself not even noticing the screen went to the next record, it happens so fast. Several new features were added as well so I will be blogging about those as well, stay tuned.....(read more)

Unable to Insert Opportunities in Infor CRM (formerly Saleslogix) Web Client

$
0
0

 I recently ran into an issue where a client was unable to insert Opportunities when logged in as particular users.  When they clicked Save they would get an error similar to this:

The statement has been terminated. : String or binary data would be truncated.
Saleslogix Error Id: SLX2AECA524F481B1D7
URL: http://localhost:3333/SlxClient/InsertOpportunity.aspx?modeid=Insert
Exception type: System.Data.OleDb.OleDbException
Source: System.Data.OleDb.OleDbCommand, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Using SQL trace I was able to see the SQL statement that was being attempted was:

INSERT INTO OPPORTUNITY
(ACTUALAMOUNT, ADDTOFORECAST, CLOSED, CLOSEPROBABILITY, CREATEDATE, CREATEUSER, DATEOPENED,
DESCRIPTION, ESTIMATEDCLOSE, EXCHANGERATE, EXCHANGERATECODE, EXCHANGERATEDATE, EXCHANGERATELOCKED,
MODIFYDATE, MODIFYUSER, SALESPOTENTIAL, STATUS, TYPE, OVERRIDESALESPOTENTIAL, ACCOUNTMANAGERID,
SECCODEID, ACCOUNTID, OPPORTUNITYID)
VALUES
(0,'F','F',50,'2014-11-20 21:15:28','ADMIN       ','2014-11-20 21:15:07',
'DESCRIPTION','2015-01-31 00:00:00',1,'United States Dollar','2014-11-20 21:15:07','F',
'2014-11-20 21:15:28','ADMIN       ',0,'Open','Existing Customer','F','U6UJ9A0000HI',
'F6UJ9A000024','AZAA2A50000N','O6UJ9A0003UE')

While that SQL looked OK, I noticed that the ExchangeRateCode was being set to "United States Dollar".

Looking at the data type definition ot the ExchangeRateCode field in the OPPORTUNITY table, I see it is a varchar(3) field.  

Hmm...

Firing up Reflector I was able to see that this is being read on the Opportunity's OnCreate Event and is being read from the UserOptions service.

This service essentially reads values from the USEROPTIONS table for the current user.

Running a SQL statement for the particular value that it was looking for to default the Currency Code is this:

select * from useroptions where CATEGORY='opportunitydefaults' and name='lveCurrency'

In my case I found that several users had their default values set to "United States Dollar" rather than the correct "USD".  This is likely a left over from previous versions having set this value differently than what is expected in the past.

Using this statement finds all the rows with an issue:

select * from useroptions where CATEGORY='opportunitydefaults' and name='lveCurrency' and len(cast(optionvalue as varchar(96)))>3

Finally, using this statement correct the issue:

update USEROPTIONS set optionvalue='USD' where cast(OPTIONVALUE as varchar(64))='United States Dollar' and CATEGORY='opportunitydefaults' and name='lveCurrency'

After the user logged out of the web client and back in (UserOptions are cached during log in) the user was now able to add Opportunities.

 

Jan 26, 2015 - Creating a Contact Process in Infor CRM

$
0
0

Attend the Workshop - Creating a Contact Process in Infor CRM!

Event details:

  • Monday, January 26, 2015
  • From 2:00 PM Central to 2:30 PM Central
    (8:00 PM GMT to 8:30 PM GMT)

See Workshop Details

Register Today!

Feb 02, 2015 - Infor CRM (Saleslogix) Web - Navigating the Web Client

$
0
0

Attend the Workshop - Infor CRM (Saleslogix) Web - Navigating the Web Client!

Event details:

  • Monday, February 02, 2015
  • From 2:00 PM Central to 2:30 PM Central
    (8:00 PM GMT to 8:30 PM GMT)

See Workshop Details

Register Today!

Feb 09, 2015 - Setting Up New Users in Infor CRM v8.x

$
0
0

Attend the Workshop - Setting Up New Users in Infor CRM v8.x!

Event details:

  • Monday, February 09, 2015
  • From 2:00 PM Central to 2:30 PM Central
    (8:00 PM GMT to 8:30 PM GMT)

See Workshop Details

Register Today!

Problems running Crystal Reports in the Infor CRM (formerly Saleslogix) LAN client

$
0
0

We recently had a client that was using the Crystal RDC object in VBScript within the LAN client to run a Crystal Report.  They were able to run the report once but the second time they tried, the report failed with a "Database Vendor Code 7" error.  Digging in I found the problem.  This was a first for me so I thought I would record it should it ever happen again.

Here is the code I was using:


    filename = Application.BasicFunctions.GetPersonalDataPath & "\" & radContractType.Text & " - " & frmSchoolContract.CurrentID & ".pdf"
    set rdc = Application.BasicFunctions.GetCrystalReport(family & ":" & report)
    With rdc
         .DiscardSavedData
         For i = 1 To .parameterFields.Count
             .ParameterFields.Item(i).ClearCurrentValueAndRange
         Next

         With .ExportOptions
                 .FormatType = 31 'crEFTPortableDocFormat
                 .DestinationType = 1 'crEDTDiskFile
                 .DiskFileName = filename
         End With
         .RecordSelectionFormula = "{SCHOOLAGREEMENTS.SCHOOLAGREEMENTSID} = '" & frmSchoolContract.CurrentID & "'"       
    msgbox .SQLQueryString
         .Export false
    End With
    Set rdc = Nothing



I added the msgbox shown in bold to see what the report was using as the SQL result set to run with.  This is what it showed the first time:

 SELECT "ACCOUNT"."ACCOUNT", "ADDRESS"."ADDRESS2", "ADDRESS"."CITY", "ADDRESS"."STATE", "ADDRESS"."POSTALCODE", "CONTACT"."FIRSTNAME", "CONTACT"."LASTNAME", "ADDRESS"."ADDRESS1", "SCHOOLAGREEMENTS"."SCHOOLAGREEMENTSID"
 FROM   (("sysdba"."SCHOOLAGREEMENTS" "SCHOOLAGREEMENTS" INNER JOIN "sysdba"."CONTACT" "CONTACT" ON "SCHOOLAGREEMENTS"."CONTACTID"="CONTACT"."CONTACTID") INNER JOIN "sysdba"."ACCOUNT" "ACCOUNT" ON "CONTACT"."ACCOUNTID"="ACCOUNT"."ACCOUNTID") LEFT OUTER JOIN "sysdba"."ADDRESS" "ADDRESS" ON "ACCOUNT"."ADDRESSID"="ADDRESS"."ADDRESSID"
 WHERE  "SCHOOLAGREEMENTS"."SCHOOLAGREEMENTSID"='QV28PB71N7PP'
 ORDER BY "ACCOUNT"."ACCOUNT"


And this is the SQL that was used when running the second time:

 SELECT "ACCOUNT"."ACCOUNT", "ADDRESS"."ADDRESS2", "ADDRESS"."CITY", "ADDRESS"."STATE", "ADDRESS"."POSTALCODE", "CONTACT"."FIRSTNAME", "CONTACT"."LASTNAME", "ADDRESS"."ADDRESS1", "SCHOOLAGREEMENTS"."SCHOOLAGREEMENTSID"
 FROM     ("sysdba"."CONTACT" "CONTACT" INNER JOIN "sysdba"."ACCOUNT" "ACCOUNT" ON "CONTACT"."ACCOUNTID"="ACCOUNT"."ACCOUNTID") LEFT OUTER JOIN "sysdba"."ADDRESS" "ADDRESS" ON "ACCOUNT"."ADDRESSID"="ADDRESS"."ADDRESSID"

 ORDER BY "ACCOUNT"."ACCOUNT"


What?  Why did the SQL get all messed up?

I found that pressing Cntlr+F5 allowed me to run the report once more, but failed on the second attempt again.

After lots of digging I found  2 things that had to be changed in order to get the SQL to not get corrupted after running the report.

  1. I had to Add at least one field from the SCHOOLAGREEMENTS table to the report layout.  That fixed the disappearing "FROM" portion of the SQL statement.
  2. After exporting (the .Export false line), I had to set the RecordSelectionFormula = empty.  That fixed the disappearing "WHERE" portion of the SQL statement.

Very strange.  I have never run into this before.  The client was on an older version of SLX so I am not sure if that had something to do with this or not. 

    filename = Application.BasicFunctions.GetPersonalDataPath & "\" & radContractType.Text & " - " & frmSchoolContract.CurrentID & ".pdf"
    set rdc = Application.BasicFunctions.GetCrystalReport(family & ":" & report)
    With rdc
         .DiscardSavedData
         For i = 1 To .parameterFields.Count
             .ParameterFields.Item(i).ClearCurrentValueAndRange
         Next

         With .ExportOptions
                 .FormatType = 31 'crEFTPortableDocFormat
                 .DestinationType = 1 'crEDTDiskFile
                 .DiskFileName = filename
         End With
         .RecordSelectionFormula = "{SCHOOLAGREEMENTS.SCHOOLAGREEMENTSID} = '" & frmSchoolContract.CurrentID & "'"
         .Export false
         .RecordSelectionFormula = empty
    End With
    Set rdc = Nothing




 

 

Recording: Infor CRM Update 05 and the Redesigned User Interface

$
0
0
Get your first look now! Whether you're planning on implementing Infor CRM Update 05, or you're just curious about what the future of Infor CRM looks like, we encourage you to watch a recording of today's webinar:...(read more)

How to Disable the ComboBox Control in the Infor CRM (Saleslogix) Web Client

$
0
0

There's a problem with the ComboBox control in the Infor CRM (Saleslogix) Web Client. It won't disable. Sure, it has an Enable property, but setting it to false has no effect on the control and it will remain enabled. However, there is a solution. Luckily, the control itself renders as a Dijit Select form widget from the Dojo UI Library so we can simply manipulate the control based on what can be done to the Dijit Select.


The Problem

As I mentioned earlier, the problem is that setting the ComboBox control's Enabled property to false does not disable the control. You'll still end up with the control looking, and worse, behaving as an enabled control (allowing the user to still interact with it).


That's no good if you want to ensure the user can only access the control if you intend that behavior.


The Solution

The ComboBox control itself actually gets added to the deployed SmartPart as an ASP.NET ListBox with a specific Dojo attribute. It will look like this on the page:

<asp:ListBox runat="server" ID="comboBox1" data-dojo-type="dijit.form.Select" SelectionMode="Single" Rows="1" CssClass="select-control"></asp:ListBox>

The magic here is the data-dojo-type="dijit.form.Select" part. At runtime, the Dojo Dijit library does it's work and changes that to a nice looking Dijit Select dropdown control, AKA the Inform CRM ComboBox. Knowing this, we can manipulate the control as a Dijit Select widget. The Dijit Select widget can be disabled by adding a "disabled" attribute with a value of "disabled" (yep, disabled="disabled").

So, to disable the ComboBox in a code snippet, in place of doing this:

comboBox1.Enabled =false;

We can do this:

// disable the comboboxcomboBox1.Attributes["disabled"] ="disabled";

This will disable the ComboBox just as you'd expect it to be. Users cannot interact with it and it looks disabled.

 

Then to enable the ComboBox:

// enable the comboboxcomboBox1.Attributes["disabled"] ="false";

 

Just as easy as using the Enable property, but the big difference is that it works :)

Get Your Hands on the Infor CRM (Saleslogix) v8.1.x Compatibility Guide

$
0
0
Download now! In December 2014 Infor quietly released the Infor CRM (Saleslogix) v8.1.x Compatibility Guide and unless you were actively searching for it you were probably unaware of its existence. It does exist and we have it for you to download! You will find the Compatibility Guide attached to this post. -Briannna ...(read more)

Limiting the Height of the Infor CRM (Saleslogix) ComboBox Popup

$
0
0

In my last post, I discussed how the Infor CRM (Saleslogix) ComboBox is a Dijit Select form widget. This opens up a few different things about what you can do to the control based on what is possible to do with the Dijit Select. For example, controlling the height of the popup list for the ComboBox.


The Problem

The Infor CRM ComboBox doesn't look so nice, or is easy for an end-user to use, once the list gets long. It's ugly and cumbersome to work with. Here's an example:


(click for larger view)

It gets even worse if the list is longer. Even to the point where it runs right off the screen and causes the entire page to keep scrolling for as long as the ComboBox gets. It just keeps getting longer and longer.


The Solution

Since the ComboBox is really just a Dijit Select widget, the Select has an attribute that can be added called maxHeight. This attribute will cause the popup list to have that height and also a scrollbars for the items that exceed that height. We can do this on a case-by-case basis by adding this attribute to the ComboBox.

comboBox1.Attributes["maxHeight"] ="200";

Then, the maxHeight will be passed along to the control on the SmartPart and get picked up by the Dojo Dijit library when it renders the control and set the height accordingly. Then, that ugly list above will end up more like this:


That is so much better. Personally, I think all ComboBoxes in the system should have this same maxHeight set. Luckily, there's a way to add this to all controls with a simple CSS style-sheet addition.

Add a new style-sheet to the css folder in the SupportFiles of the portal with the following:

.dijitSelectMenu
{
    max-height: 200px !important;
    overflow-y: scroll !important;
}

(Don't miss that "." before the dijitSelectMenu). Also, open the base.Master and add the stylesheet there as well. Then, the style will apply to all ComboBox popup lists in the system and no need to set it on a per-control basis.

Required Secured Actions to Run a Report in the Infor CRM v8.1 Web Client

$
0
0

We recently had a client complaining users could not run reports in their upgraded Infor CRM v8.1 web client.  The Run Report and Schedule Report tasks in the Report manager area were not showing.  These common tasks are constructed in javascript.  They assume pre-existing secured actions exists and that these secured actions belong to user roles.  The required secured actions are (case sensitive):

  • 'Entities/ReportManager/RunReport',
  • 'Entities/ReportManager/ScheduleReport',
  • 'Entities/ReportManager/EditSchedule',
  • 'Entities/ReportManager/DeleteSchedule'

These secured actions are added as part of the external exe to be run during the v8.1 upgrade.  Running that tool allowed the reports to be run by the user.

Creating a Searchable & Filterable ComboBox in Infor CRM (Saleslogix) Web Client

$
0
0

I've had a few posts lately covering the ComboBox control in the Infor CRM (Saleslogix) Web Client (here and here). The ComboBox itself isn't too exciting. However, as I've mentioned in the previous posts, the fact that the Infor CRM ComboBox renders as a Dijit Select form widget makes it so much more powerful due to the fact that you can use it as a Dijit Select widget and not just as an ASP.NET control. In this post, we'll look at changing the widget type of the ComboBox to a filterable widget to make it even more useful. We can change the ComboBox so a user can type and the list will automatically filter to show the items matching as the user types - and do it with a single line of code. Pretty cool, right?

I posted before about using large lists in the ComboBox control. How the list becomes difficult to work with with a lot of items. Limiting the size of the list was only a stop-gap solution. It makes it a little easier to work with, but a user looking for an item on that large list still has a lot of items to look through. It's still a pain. So, what if we could make that list searchable or filterable? That would make the list so much easier to work with. A user could use the list as as normal ComboBox or they could just start typing what they are looking for and the list would automatically and immediately filter. That would be great. Fortunately, that's an easy, one-line of code solution.


The Dijit FilteringSelect Widget

When a QuickForm gets converted to a deployable ASP.NET UserControl when you build and deploy, the ComboBox control actually gets added as an ASP.NET ListBox like this:

<asp:ListBox runat="server" ID="comboBox1" data-dojo-type="dijit.form.Select" SelectionMode="Single" Rows="1" CssClass="select-control"></asp:ListBox>

The real magic happens because of the data-dojo-type="dijit.form.Select". This tells the Dojo Dijit UI library to change this element to a Select widget and it ends up looking like a nice looking ComboBox. The Dijit Select widget is only one of the "list" or "combo" type of widgets in the Dijit UI library. What we want to do is convert it to a Dijit FilteringSelect widget. The FilteringSelect widget has this filtering functionality built right in. Converting from the Dijit Select widget to a Dijit FilteringSelect is just a simple task of changing the data-dojo-type attribute for the control.


Making the Change

Changing the ComboBox from being a Dijit Select to a Dijit FilteringSelect is a one line of code change. Let's do it.

comboBox1.Attributes["data-dojo-type"] ="dijit.form.FilteringSelect";

That's it! So, what did that do? With that one simple change, the Dojo Dijit UI library will convert the control to a FilteringSelect (instead of a Dijit Select) and you get all the functionality of a FilteringSelect along with it. This is what it looks like in action:


The whole thing works just like a normal ComboBox, you just get the filtering stuff along with it. The user can select from the list like a normal ConboBox OR the user can type in a value and the list will filter as the user types to show the matching values. Even with typing in the value, you still get the change action to fire when an item in selected.

In my opinion, that's pretty cool stuff.

Viewing all 981 articles
Browse latest View live