Pages

Thursday, December 30, 2010

EP pop-up windows with checkboxes

When building pop-up windows with checkboxes it seems like you can't make the pop-up fields with a checkbox as target. When later reading the value of the pop-up field it always returns “on”.

So with checkboxes you must write the value yourself when closing the pop-up window.

Here is an example. First some code from my pop-up parent:
protected void AddChangeInvoiceBlockScript(SetMenuItemPropertiesEventArgs e, DataSetViewRow row)
{
    AxUrlMenuItem menuItem = new AxUrlMenuItem(BLOCK_DIALOG);

    if (row != null)
    {
        AxTableContext context = AxTableContext.Create(row.GetTableDataKey(row.DataSetView.Metadata.RootDataSource, null));

        menuItem.MenuItemContext = context;

        menuItem.RemoveNavigation = true;

        e.MenuItem.ClientOnClickScript = this.PopupChangeBlocked.GetOpenPopupEventReference(menuItem);
    }
}

And next initialization code and ButtonOK code from my pop-up:
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        CheckBoxBlock.Focus();

        IAxaptaRecordAdapter    ledgerJournalTransRecord;
        AxBaseWebPart           webpart = AxBaseWebPart.GetWebpart(this);

        if (webpart.ExternalContext != null)
        {
            ledgerJournalTransRecord = webpart.ExternalContext.DataKey.GetRecord(this.AxSession);
            if (ledgerJournalTransRecord != null)
                if ((int)ledgerJournalTransRecord.GetField(LEDGERJOURNALTRANS_WMAPRBLOC) == 1)
                    CheckBoxBlock.Checked = true;
        }
    }
}

protected void OkButton_Click(object sender, EventArgs e)
{
    try
    {
        string fieldValueBlock = CheckBoxBlock.Checked ? BLOCK_YES : BLOCK_NO;
         
        // Set the value based on the state of the checkbox
        popupChild.SetFieldValue("hiddenBlockField", fieldValueBlock);

        // Calling the script for closing the dialog box
        this.popupChild.ClosePopup(true, true);
    }
    catch (Exception ex)
    {
        AxExceptionCategory exceptionCategory;
        // This returns true if the exception can be handled here
        if (!AxControlExceptionHandler.TryHandleException(this, ex, out exceptionCategory))
        { 
            // The exception was fatal - in this case re-throw the error
            throw;
        }
    }
}

And finally closing code from my pop-up parent:
void PopupChangeBlocked_PopupClosed(object sender, EventArgs e)
{
    // Get the value of the Blocked check box
    bool block = this.PopupChangeBlocked.GetFieldValue("hiddenBlockField") == "1" ? true : false;

    // Send the value to the dataset, which will handle the update 
    this.dsWMAprApprovalList.GetDataSet().DataSetRun.AxaptaObjectAdapter.Call("setWMAprBlock", block);

    // Clear popup values
    this.PopupChangeBlocked.ClearFieldValues();

    // Refresh the grid
    this.gridWMAprApprovalList.DataBind();
}

You can see another example on how to use checkboxes with pop-ups in the
TSTimesheetDeleteYesNo User Control.

Other resources:
Pop-up Windows on MSDN
AxPopupParentcontrol on MSDN
AxPopupChildControl on MSDN
Solution Monkey "Devlopers Cookbook"

Thursday, October 28, 2010

Parsing a custom parameter from a user control to a data set used on another user control

The scenario is that one user control redirects to a page with another user control, and you need to pass a custom parameter for consumption by the dataset of the user control you redirect to.

See the following Word document for at proposed solution:

Using X++ to figure out which user the AOS runs under

This code will give you the AOS accounts domain and username:

public static void main(Args args)
{
    InteropPermission   permission;
    str                 userName;
    str                 userDomain;
    ;
    permission = new InteropPermission(InteropKind::ClrInterop);
    permission.assert();
    userDomain  = System.Environment::get_UserDomainName();
    userName    = System.Environment::get_UserName();
    info(strFmt(@"%1\%2", userDomain, userName));
}

The code must be executed from the server tier.

Thursday, July 22, 2010

CSS Reference Chart for SharePoint 2007

Heather Solomon has an extensive guide to all the major CSS element used on MOSS and WSS v3 sites.

Really usefull if you need to change some of the styles.

http://www.heathersolomon.com/content/sp07cssreference.htm

Tuesday, June 29, 2010

When sysMailer.quickSend isn't sending any mails

After rather many hours of debugging and hairpulling, I have figured out that you in order to send mails with sysMailer.quickSend, must have View rights to the security key Adminstration / Daily. You don't need to have access to any of the subnodes however.

The cause is that sysMailer.quickSend in order to find the password to the SMTP server, calls SysEmailSMTPPassword::currentAOSInstance, which again makes a select statement to the SysServerSessions table.

The SysServerSessions table must somehow be linked to the above mentioned security key, because without access to this, AX simply exits the metod on that select statement, just as if it had hit a Return statement - and no errors or other hints about the mail not being sent are displayed.

Monday, June 28, 2010

Coloring individual lines in an Enterprise Portal grid

Here's the code you need in order to color individual lines in an Enterprise Portal grid. The example is carried out in the CustomerListGrid user control.

First add an event handler for data binding of the grid:

if (this.AxGridView1!= null)
{
    this.AxGridView1.RowDataBound += new GridViewRowEventHandler(AxGridView1_RowDataBound);
}
Next add the code controlling the logic of the coloring. In this case lines are colored "beige", if the currency of the customer is "USD":
void AxGridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    Microsoft.Dynamics.Framework.Data.Ax.DataSetViewRow dataRow = null;
    string currencyCode;

    if (e.Row != null && e.Row.RowType == DataControlRowType.DataRow)
    {
        dataRow = (Microsoft.Dynamics.Framework.Data.Ax.DataSetViewRow)e.Row.DataItem;
        currencyCode = (string)dataRow.GetFieldValue("Currency");
            
        if (currencyCode == "USD")
        {
            e.Row.BackColor = System.Drawing.Color.Beige;
        }
    }
}
I my personal opinion colored rows are disturbing to the eye, and I would prefer to add an icon to the lines which should have special attention. You can see how to do that on the ActivityListGrid user control.

Saturday, May 8, 2010

Important SQL Server change

A new SQL Server change may substantially improve the overall performance of Dynamics AX.

Read more on the Dynamics Ax Performance Team Blog.

Monday, May 3, 2010

Interview about workflow in version 6.0 of AX.

Interview revealing details about Workflow in version 6.0 of AX.

Get Microsoft Silverlight

How to be productive with SSRS and Dynamics AX 2009: A new approach

"How to be productive with SSRS and Dynamics AX 2009: A new approach" is the title of new blog series published by Saveen Reddy , Lead Program Manager - Dynamics AX Business Intelligence, from Microsoft.

Looking very much forward to follow it.

http://blogs.msdn.com/saveenr/archive/2010/05/01/how-to-be-productive-with-ssrs-and-dynamics-ax-2009-a-new-approach.aspx

Sunday, April 25, 2010

Free ebook: Introducing Microsoft SQL Server 2008 R2

Another free ebook from Microsoft Press: Introducing Microsoft SQL Server 2008 R2

The 10 chapters and 216 pages cover:
  • Part I: Database Administration
    • Chapter 1: SQL Server 2008 R2 Editions and Enhancements
    • Chapter 2: Multi-Server Administration
    • Chapter 3: Data-Tier Applications
    • Chapter 4: High Availability and Virtualization Enhancements
    • Chapter 5: Consolidation and Monitoring
  • Part II: Business Intelligence Development
    • Chapter 6: Scalable Data Warehousing
    • Chapter 7: Master Data Services
    • Chapter 8: Complex Event Processing with StreamInsight
    • Chapter 9: Reporting Services Enhancements
    • Chapter 10: Self-Service Analysis with PowerPivot
Read more here: http://blogs.msdn.com/microsoft_press/archive/2010/04/14/free-ebook-introducing-microsoft-sql-server-2008-r2.aspx

Or download in XPS format here or PDF format here.

Tuesday, April 20, 2010

Messed up Product Builder lookups

Users are able to right click and change some of the lookup's in the Product Builder configuration form. This way they can by accident hide the entire lookup and not be able to use it again, before someone deletes the change from their Usage Data.

To avoid this issue, set the property AllowUserSetup on the design of the PBATableVarLookup and PBAVariableEnumLookup forms to No.

Sunday, February 21, 2010

Free ebook: Understanding Microsoft Virtualization Solutions (Second Edition)

Mitch Tulloch has updated his free ebook of last year; it’s now updated for Windows Server 2008 R2. You can now download Understanding Microsoft Virtualization Solutions, From the Desktop to the Datacenter in XPS format here and in PDF format here.

Six chapters adding up to 466 pages.

Wednesday, February 17, 2010

It is possible for users to edit the Item reference fields of sales order lines and purchase order lines.


It is possible for users to edit the Item reference fields of sales order lines and purchase order lines of a user adds these fields to the forms.
Hopefully no adventurous end users read this post.

Repro:

  1. Open Sales Order Details
  2. Go to Lines / Other
  3. Select one the Item reference fields
  4. Note that you cannot change the values
  5. Right click in the form and select Setup
  6. Select the Line / TabLine/Lines/SalesLineGrid node
  7. Click Add fields
  8. Expand Order lines
  9. Select for example the Reference number (InventRefId) field
  10. Close the selection form
  11. Close the User setup form
  12. Observe that the Reference number field is now added to the grid, and you can edit it.

Obviously if you tamper with the references of the lines, you will destroy the integrity between the references entities, links are broken, and subsequent actions will not perform as expected.

You should lock these fields on datasource field level by setting the AllowEdit property to No. Maybe you should even consider setting the AllowEdit property to No on the table level. I'm not sure if the later suggestion causes any problems elsewhere in the application, but I can't imagine a place where you'd want users to edit these fields manually.

Here are the fields where you should set AllowEdit=No if you want a fix at table level:
AOT > Tables
  • SalesLine > Fields >
  • InventRefTransId
  • InventRefType
  • InventRefId


  • PurchLine > Fields >
  • InventRefTransId
  • InventRefType
  • InventRefId

Friday, February 5, 2010

Datasource names on Data Sets used for custom lookups on Enterprise Portal

When creating lookups based on a User Control in the AOT, it seems required that you, in the query of the dataset, make sure the datesource name and table name is exactly the same for each datasource.

Normally you would be able to name the datasource differently from the table it represents, but the EP frameworks can't figure this out when you apply custom filters from the webpage.

It fails when applying the filter, being unable to update the query on the dataset.

Sorting of versions shown in the Compare tool, when using MorphX version control, is not correct

When using the Compare tool from an AOT node in a system with MorphX version control enabled, the order of historical versions for the object is not shown as intended.

The Compare tool is intended to show the first version and the twenty latest versions of the object. In this case however you get the twenty first versions. This is because the Compare tool uses the change numbers of the object to figure out the sorting, but the change number with MorphX version control is always 0.

To fix this, make the following change to \Classes\SysTreenodeCompareContext\comparableListTreenode, lines 110-111:

while select item
    order by ChangeNumber desc, Version asc
with
while select item
    order by ChangeNumber desc, Version desc
This is obviously just a quick fix, but will work as intended until Microsoft fixes the bug.

Thursday, January 28, 2010

Important limitation in Enterprise Portal deployment


You cannot out of the box run multiple EP sites, with different versions of User Control code, on the same IIS.

This is because SharePoint expects the code to be under the %System drive%:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\ep folder and you cannot deploy to different folders.

A workaround where you map the layout folder differently for each site, is described in KB944105. But it has some conequences, which you can read more about in the knowledgebase article.

Friday, January 22, 2010

Create a base64 encoded string from an image in AX

Here's how you can create a base64 encoded string from an image in AX:

static void Job4(Args _args)
{
    System.Drawing.Image     image;
    Str                      string;
    System.IO.MemoryStream   memoryStream;
    ;

    // Load the file
    image = System.Drawing.Image::FromFile(@"C:\sandbox\test.tif");

    // Convert the file to a memory stream
    memoryStream = new System.IO.MemoryStream();
    image.Save(memoryStream, System.Drawing.Imaging.ImageFormat::get_Tiff());

    // Create the base64 encoded string
    string = System.Convert::ToBase64String(memoryStream.ToArray());

    // Save it again, to a new image (just for fun or test if you want)
    AifUtil::saveBase64ToFile(@"C:\sandbox\test1.tif", string);
}

Convert an image from one format to another from AX

Here's is how you can convert an image from one format to another:

static void Job5(Args _args)
{
    System.Drawing.Image    image;
    ;

    image = System.Drawing.Image::FromFile(@"C:\sandbox\test.tif");

    image.Save(@"C:\sandbox\newtest.jpg", System.Drawing.Imaging.ImageFormat::get_Jpeg());
}

The new files tend to be a bit larger. You have to work with the ImageCodecInfo class from .NET to fix this.

Thursday, January 21, 2010

Annoying bug in AX 2009 Intercompany Sales Order

Here is a really annoying bug in AX 2009 intercompany sales order, causing errors where it can take you ages to figure out the cause.

When adding items to an older intercompany order, the intercompany chain is not started. The user needs to pay much attention to realize that the chain is not started and there is not easy way to start it, once the sales order lines is saved.

Repro steps:
Go to company CEE.
Create a new sales order (customer should not be important, but use for example 1102).
Go to the "Other" tab of the sales order header, and check the "Autocreate intercompany orders" check box.
Go to the "Delivery" date tab page.
Enter values for Confirmed Receipt and Confirmed Shipping Dates.
Add an item line for item 1101.
Move the cursor away from the sales order.
At this point the system will generate the intercompany.

Now change the sessions date to a date after the Confirmed Shipping date of the order.

Go back to the order.
Add one more line for 1101.
When saving the record you should get a warning like this: "Item number 1101, requested shipping date 12/3/2009 is in the past.".
The order line is now saved.
Move the cursor away from the sales order.
Nothing happens - the intercompany order has not been updated with the new order line and I see no way that I can trigger the system to generate the line, other than changing dates of the order, delete and recreate the line..

Business impact:
The first problem is that if users aren't paying proper attention to this warning, they'll never get the intercompany chain started on order. And they will not know about it, until they realize that the items aren't delivered.
The second problem is that there is no way to change the dates and the get the intercompany chain started, unless you delete the sales order line and recreated. If you use the product builder to configure items for the sales order, this could be a bit of a pain to do.

Resolution:
Microsoft is considering fixing this issue for AX 2011, but sees it as a matter of educating the users...