Drilling back to Project Accounting Inventory Transfer Inquiry Zoom

Patrick Roth - Click for blog homepageA few days ago, a user posted a question on the Dynamics GP forums.

What he ran across was when drilling back to the source document from the (GL) Transaction Entry Zoom window for a Project Accounting Inventory Transfer document, the document didn't display correctly.  If the journal entry is in the Open status or other document types this works fine.  But a journal entry from a historical year for the PA Inventory Transfer doesn't work.

Above is the General Ledger Transaction Entry Zoom window to show us the journal entry of the transaction.

From the screenshot, we can see the source document is Project Accounting - PAINV and the reference shows that it is indeed from the Inventory Transfer Entry window.

If we click the hyperlink on Source Document, it should drill back ot the Zoom window for that transaction.

The Inventory Transfer Entry Window opens so we're going to the right place.  But clearly we can see the document isn't displaying correctly.

Looking more closely, the issue is that the Document Number field isn't really the document number.  It looks more like an Audit Trail code.  And it is.

If we look at the (edited) script.log I captured, we can see what happens.

'PA_Zoom_From_GL_History_Trigger'
    'PA_Zoom_MDS_From_GL_History_Trigger', 0
        'SQLPath', 258, 1, 5, ""
    'SQLPath', 258, 6, 22020, ""
    'Security', 258, 2, 22292, ""
        'Security()', 0, 258, 2, 22292, "", 1
<snip>
    'SQLPath', 258, 6, 22019, ""
    'SQLPath', 258, 6, 22020, ""
    'SQLPath', 258, 6, 22019, ""
    'SQLPath', 258, 6, 0, ""
    'PA_Inquiry_Zoom_Inventory_WIN_PRE on form PA_Inquiry_Zoom_Inventory'
        'PA_Inquiry_Zoom_Inventory Dummy Note Show Hide_CHG on form PA_Inquiry_Zoom_Inventory'
            'Check_For_Note', "Inventory Transfer Inquiry Zoom", 0
<snip>
    'PA_Inquiry_Zoom_Inventory Display Existing Record_CHG on form PA_Inquiry_Zoom_Inventory'
        'SQLPath', 258, 6, 22020, ""
        'Display Document of form PA_Inquiry_Zoom_Inventory', table 'PA_IV_Transfer_HIST_HDR',
               table 'PA_IV_Transfer_HIST_LINE', "PAIV00000002", 0
 

At the top of the script.log, we see that a trigger is running on our "click" of the hyperlink.  Technically we can't tell that it is a trigger as the hidden button script could be called this.  But the "PA" and "Trigger" make it somewhat obvious that Project Accounting is running to see if it needs to drill back to a window.  In this case, that is true.

On the last line, we do see the "document number' being passed though we don't know for sure what the value should be.

Or don't we?

If we look at the SDK, it tells us the params for the procedure 'Display Document of form PA_Inquiry_Zoom_Inventory' are:

in anonymous table HDR_Table;
in anonymous table DTL_Table;
in 'PA IV Document No' l_doc_no;
optional in integer l_void = 0;

 

From the 3rd parameter, we can verify that it really should be the Document Number and not the Source Document/Audit Trail as it being used.

I won't show the script.log for it (you can do this as an exercise) but if we were to drill back for an open GL transaction we would see the PA Document Number being passed so we know that is the correct behavior.

As it turns out - Pam from Dynamics GP support confirmed that what we are seeing is bug 50970. 

So the question is: Can we work around this?

Out of the box in GP, no.  However if we were to use a developer tool to work around this then possibly it can be done.

 

As I see it there are a couple possibilities:

  1. We can trigger on the click event and open the window correctly.
     
  2. We can let PA open the window and attempt to 'fix' the Document Number to be the real value.

If we use Dexterity, then #1 would be easy.  However not really possible with vstools because vstools triggers run last and that means PA will run first no matter what.

#2 isn't a bad idea and the one I think I'd go with. 

Looking at the script.log, we can see the 'Display Existing Record' script being invoked.  It is nice to see that the field is named something "typical" as that is a very common field used by many windows which actually does the work to display a document.

That script calls 'Display Document' which passes in the value we need.  This most certainly is the field 'PA IV Document No' field on the window.

So how then we we force the window to display the correct document?

At first I was thinking to display the document, I would just call the 'Display Document' procedure.

But that does't work so well because VSTools can't call this one due to the anonymous tables.  Also, we don't know if the tables should be positioned or not and we don't know any logic that 'Display Existing Record' might contain. 

So after thinking about it, it seems the best idea is to just re-do the call to 'Display Existing Record' - that way we don't need to worry about what the function does.

The only problem I see is how do we know if we should execute our code or not?  Perhaps the document displayed correctly after all?

So that seemed like an issue until I realized:

  1. The Transaction Type field will be empty if this issue occured.
     
  2. By checking to see if the Transaction Entry Zoom window is open and if so, the Audit Trail for the selected Journal Entry is the one on the Inventory Transfer Inquiry zoom window.  If so then we must have come from there.

Below is the code I used in my Visual Studio 2010 project using Microsoft Dynamics GP 2010.  It references the Application.Dynamics.dll & the Application.ProjectAccounting.dll to gain access to the GP & Project Accounting resources respectively.

I commented the code pretty well so it should be easy to follow on why I coded the application as I did.

C# Code Example of the GPAddins.cs file

// Copyright © Microsoft Corporation.  All Rights Reserved.
// This code released under the terms of the
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Dexterity.Bridge;
using Microsoft.Dexterity.Applications;
using Microsoft.Dexterity.Applications.DynamicsDictionary;
using Microsoft.Dexterity.Applications.ProjectAccountingDictionary;

namespace PA_IV_Transfer_Zoom
{
    public class GPAddIn : IDexterityAddIn
    {
        // IDexterityAddIn interface
        static bool bInTrigger = false;

        public void Initialize()
        {
            ProjectAccounting.Forms.PaInquiryZoomInventory.PaInquiryZoomInventory.DisplayExistingRecord.ValidateAfterOriginal += new EventHandler(Zoom_Inquiry_DisplayExistingRecord_ValidateAfterOriginal);
        }

        void Zoom_Inquiry_DisplayExistingRecord_ValidateAfterOriginal(object sender, EventArgs e)
        {  
            if (ProjectAccounting.Forms.PaInquiryZoomInventory.PaInquiryZoomInventory.LocalDocumentType.Value == "")
            {
                //check our local, if set then exit
                if (bInTrigger == true)
                {
                    return;
                }

                // If the LocalDocumentType is empty then likely because of bug MBS 50970
                // check to see if the document displayed is one that came from the GL History Zoom window.
                // We can do that by seeing if window is open and the audit trail matches
                // the document number displayed on the window.
                // If not, then do nothing.  If so, then we'll set the actual doc number and execute the Display script
                if (Dynamics.Forms.GlZoomHistoryTransaction.IsOpen == true)
                {
                    string sOrigTrxSource = "";
                    string sOrigDocNumber = "";
                    sOrigTrxSource = Dynamics.Forms.GlZoomHistoryTransaction.Tables.GlTrxHistByAcctTemp.OriginatingTrxSource.Value;
                    sOrigDocNumber = Dynamics.Forms.GlZoomHistoryTransaction.Tables.GlTrxHistByAcctTemp.OriginatingDocumentNumber.Value;

                    //Check if GL Trx Source is the Doc No on window, so must have drilled back from there.
                    if (ProjectAccounting.Forms.PaInquiryZoomInventory.PaInquiryZoomInventory.PaIvDocumentNo.Value == sOrigTrxSource)
                    {          
                        //Set the flag
                        bInTrigger = true;
                        //set the doc number to the real value
                        ProjectAccounting.Forms.PaInquiryZoomInventory.PaInquiryZoomInventory.PaIvDocumentNo.Value = sOrigDocNumber;
                        //and then force PA to display this record.
                        //this will end up making this event script run again but flag set and we'll exit out at that point
                        ProjectAccounting.Forms.PaInquiryZoomInventory.PaInquiryZoomInventory.DisplayExistingRecord.RunValidate();
                        //We are back again from original call - reset the flag
                        bInTrigger = false;
                    }
                }
            }
        }
    }
}

After deploying my assembly to the Addins folder and re-launching Dynamics GP with it installed, we can see that the document now displays correctly.

 

My Visual Studio 2010 project created with Microsoft Dynamics GP 2010 and the compiled assembly is attached to this post. 

To install, copy the PA_IV_Transfer_Zoom.dll to your Addins folder and launch Dynamics GP.

As noted in the License Agreement in the code example and solution file, this customization is provided as-is and without support.

[EDIT 02/27/12: Ow, Ow, Ow. OK, I'll do it. David twisted my arm and convinced me that I should write this workaround as a SDT non-logging trigger. I've done so and attached the project combined with the previous VS solution to this post as PA_IV_Transfer_Zoom_Combined.zip.]

Patrick Roth
Dynamics GP Developer Support 

PA_IV_Transfer_Zoom_Combined.zip