Friday, October 12, 2018

AX Workflow 'Stopped (error):'

I received this error on my Timesheet workflows.  There is no error given in the workflow nor in ANY event logs.

The solution actually ended up being pretty simple.  A reboot of our AX AOS Batch Server solved the issue.

Monday, September 17, 2018

The User Control has caused a compilation error

After moving some code into my testing environment, I received the following error:


Message: The User Control ESSActivityPicker.ascx has caused a compilation error. To view details about this error, enable debugging in the web.config file or view the Windows event logs.

Source: System.Web

Exception details:

c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ep\ESSActivityPicker.ascx.cs(33): error CS0234: The type or namespace name 'EPGlobalParameters' does not exist in the namespace 'Microsoft.Dynamics.Portal.Application.Proxy' (are you missing an assembly reference?)

at System.Web.Compilation.AssemblyBuilder.Compile()
at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()
at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResult(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean ensureIsUpToDate)
at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath)
at Microsoft.Dynamics.Framework.Portal.UI.WebControls.AxUserControlUpdatePanel.LoadControl()

Now, the reason for moving code was to fix this control and fix the error listed above.  When I opened the control up on VS 2010, line 33 is commented out and should not be in error.  When I compiled in VS, it compiled just fine.

After searching for a while I finally gave up and went on my EP server.  I browsed out to the 'ep' folder listed in the error and checked the file.  Sure enough, my changes to code were NOT reflected in this file. 

I simply edited the file, commented out the code, and then tried EP again.  It worked!  No issue at all any more.

Thursday, August 30, 2018

System can't cast 'LedgerJournalEngine)' to 'LedgerJournalEngine_VendInvoice' in Batch

I came across an issue recently where my Timesheets wouldn't post in 'Batch'.

It turns out that it wouldn't perform the following code in 'Batch', but would be fine doing it in the Client.

LedgerJournalEngine_VendInvoice         ledgerJournalEngine;
ledgerJournalEngine = LedgerJournalEngine::construct(LedgerJournalType::VendInvoiceRegister);

If we go to the 'construct' method, we will see it returns the 'default' in the switch case:

default :
            ledgerJournalEngine = new LedgerJournalEngine(_formRun);

When running this in the client, it works fine.  When running it in 'Batch' on the server, it fails:

Unable to cast object of type 'Dynamics.Ax.Application.LedgerJournalEngine' to type 'Dynamics.Ax.Application.LedgerJournalEngine_VendInvoice'.

This does make sense that you can't cast a 'Child' class to it's 'Parent', however, why would this work on the Client but not in Batch?

UPDATE:

The answer here is that in X++, this is allowed.  Thus, the client works.
In CIL, it is a bit more strict and it is not allowed, therefore it fails in 'Batch'

Simple solution is to just make this 'LedgerJournalEngine'.  That is the type that is being returned anyway so it works just fine.

Monday, August 20, 2018

AX 2012 Enterprise Portal - Server error in '/' Application

After performing a code deployment (modelstore import), we attempted to update our 2 EP Websites with:
axupdateportal -updateall -websiteurl https://mySite.mydomain.com/Sites/DynamicsAX
With each one having it's own 'mysite' address.
1 of our sites worked perfectly, however, the 2nd site wouldn't allow axupdateportal to run due to this error:
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:10:00'. ---> The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:10:00'. ---> The read operation failed, see inner exception. ---> The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:10:00'. ---> An existing connection was forcibly closed by the remote host

When navigating to the site this is what we see:

If you could scroll all the way to the bottom, it would seem that ALL 'Proxies' are showing the same error of:
CS0234: The type or namespace name 'AX' does not exist in the namespace 'Microsoft.Dynamics' (are you missing an assembly reference?)
After doing some reasearch, I found this post and video. This video turned me on to my web.config file which had the same problem as in the video.  My web.config file had NO reference to Dynamics.  
Thankfully, I had a backup of this file from a few days prior.  Once I put the correct web.config file in worked perfectly.
However, I am still unsure about the 'socket' error I was getting when trying to use AxUpdatePortal... To be continued...


Thursday, August 16, 2018

AxUpdatePortal 'Document Moved' error

When trying to run AxUpdatePortal -UpdateUrl -websiteurl https://myWebsite.domain.com/Sites/DynamicsAx I was receiving the following error:


System.Net.WebException: The request failed with the error message:
--
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="https://uat-ep01.vipernet.net/_layouts/EPDeploymentService/EPDeploymentService.asmx">here</a></body>
--.
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at Microsoft.Dynamics.Framework.Deployment.Services.EPDeploymentService.DeployEnterprisePortal(String virtualServer)
   at AxUpdatePortal.Program.Deploy(String[] args, String webSiteUrl)
   at AxUpdatePortal.Program.Main(String[] args)

This simply ended up being the wrong 'domain.com'.  Once I put in the correct domain, all was well.

Wednesday, August 8, 2018

First record in 'RecordInsertList' had incorrect company

We recently had a situation where (Long story short...) the first record from a 'RecordInsertList' was showing the data area id of the batch job it was run under and the other 3 were correctly showing the company from 'changeCompany()'.

Here is the original code (From a 3rd party):

 MyTable myTable;
 RecordInsertList myRecordInsertList;
 myRecordInsertList= new RecordInsertList(myTable.TableId);
 while (myEnumerator.moveNext())
 {
    [Get the company you need]
    changeCompany([company])
    {
      myTable.Field1 = field1
      ....
      myTable.Insert();
    }
 }
 
The first record, in some instances, will have the data area id that doesn't match what you changed it to in 'changeCompany'.  Very interesting.  This was causing some other functionality to fail as it was doing a 'select' on myTable but not cross company.

Here is the solution:

changeCompany([comapny])
{
   myTable = null;
   myTable.Field1 = field1
   ....
   myTable.Insert();
 }

This fixes the problem.  I suspect that the 'mytable.TableId' might be instantiating the myTable buffer 'DataAreaId' and it doesn't ever get corrected.
On top of the above fix, I would also do:

myRecordInsertList = new RecordInsertList(tableNum(MyTable));

I don't know if this would fix the problem (I suspect it would), however, it seems to be a better to handle this.

UPDATE:
After running some tests, I have confirmed that 'tableNum(Mytable)' fixes the issue.  When you do 'myTable.TableID', it instantiates the table buffer with the curExt() in 'dataArea'.  As above, when you continue on to filling the fields in the table, the 'dataArea' is wrong.

I think one could use either myTable = null or myTable.Clear() so long as the 'clear()' method is called after the 'changeCompany()'

Special thanks to Ben for helping me out with this one.

WCF 'The server has rejected the client credentials'

We are working through a request where our homegrown app is going to be on a different domain than AX.  Up until now, they have been on the same domain.

When testing our WCF connection into our inbound port into AX, we kept getting 'The server has rejected the client credentials'. 

I decided to write a small .NET console app to test and see if I could duplicate this error:

MyServiceReference.MyAXWCFService service = new MyServiceReference.MyAXWCFService();
service.ClientCredentials.UserName.UserName = "myUser@domain.com"
service.ClientCredentials.UserName.Password = "IncorrectPassword"
...
[Call methods from AX]
...

Wierdly, this worked, even though I have an incorrect password. 
After researching I found that it was using the windows credentials of my user that I used to log on to the machine to use VS 2015.

To do this correctly you need do the following:

service.ClientCredentials.Windows.ClientCredential.UserName = "myUser@domain.com"
service.ClientCredentials.Windows.ClientCredential.Password = "IncorrectPassword"

The 'Windows.ClientCredential' is what we need to use to set the Windows Credentials.  When you do this, you will then get the 'The server has rejected the client credentials' error. 

We could then specify the correct credentials in our homegrown app code, on a different domain and it will successfully connect into AX.

Hard coding a username and password like this isnt' the best idea, however, for testing purposes it does show that we can get our WCF across different domains.

Tuesday, March 13, 2018

AX Compile error - CREATE TABLE permission denied in database 'tempdb'.

While doing a full compile in AX, I received the following error:


I know that permissions hadn't changed so it couldn't have been an issue with that.
Recently, some maintenance had been performed on this environments SQL and AOS servers so I decided to give SQL a reboot first, followed by the AOS server.

This did the trick!  Compile worked fine after that.

Friday, February 2, 2018

Update conflict occured

Lately I have been getting a few of these errors on Time Sheets and Expense reports when trying to Submit:

Cannot edit a record in Timesheet weekly hours (TSTimesheetLineWeek).
An update conflict occurred due to another user process deleting the record or changing one or more fields in the record.

It always appears to be one of the lines in the time sheet.  If I remove the offending line, it will submit without issue.

Not sure why the line is showing that error.  Each line is a different customer but when we do 2 timesheets with their own Customer, everything works ok.

This may be related to an enhancement done by our partner.

I found a post that I think was related to this.  The poster gave me this to clean out the Database log to fix this error:

System administration -> Inquiries -> Database -> Database Log -> Clean up log



I left the query blank so it would clean up all log entries.

Many thanks to DAX_ajsqd2 on the AX Forum for helping me out with this! 

Thursday, January 18, 2018

Ledger account is not among accounts in account group

In working with my customer, I found that they were needing to do a VAT adjustment for a customer invoice that shouldn't have charged VAT.  They were able to credit the customer, but didn't really do it the right way.

Here is how I achieved the adjustment via General Journal.

Here is the scenario:

1. Customer was invoiced and charged VAT on the invoice.
2. Customer should not have been charged VAT and therefore needed a credit of the VAT amount.
3. Due to the situation they were in at the time (Long store... ...), they created a Journal to get that credit to the customer.
4. The journal went from the 'Customer' to an offset account.  This is some sort of holding account. (NON VAT account).
5. Now, we are trying to create a journal that will move the refund from that holding account into the proper VAT account.
6. When adding in the 'VAT COde' on the 'General' tab, we get the following error:
Ledger account [holding account] is not among the accounts in account group [Ledger Posting Group] that are used for VAT code [VAT Code]
This was true as my 'holding account' was not part of my Ledger Posting Profile under VAT in GL.
However, it still didn't  make sense.  To get this to work I had to:
1. Make the 'Account' in the journal line be the VAT account
2. Make the 'Offset account' in the journal line be the non-VAT 'holding account'.
3. Set my amount as a debit.
4. Set my VAT code.
5. POST!

Worked great!

Wednesday, January 17, 2018

Cannot execute a data definition language command on

While posting a timesheet, one of my users received the following error:

Cannot execute a data definition language command on Source document line (SourceDocumentLineTmpJournalize). Reference table ID: 0, None.
The record already exists.

INSERT INTO tempdb."DBO".t101281_3FFE3B67AFC840C6A35FBD063AF9DA46 (ISFINAL,TYPEENUMNAME,TYPEENUMVALUE,STATUS,SOURCEDOCUMENTHEADER,PARENTSOURCEDOCUMENTLINE,SOURCERELATIONTYPE,EXCHANGERATEDATE,SOURCEDOCUMENTLINE,ACCOUNTINGDATE,RECVERSION,PARTITION) SELECT T1.ISFINAL,T1.TYPEENUMNAME,T1.TYPEENUMVALUE,T1.ACCOUNTINGSTATUS,T1.SOURCEDOCUMENTHEADER,T1.PARENTSOURCEDOCUMENTLINE,T1.SOURCERELATIONTYPE,T1.EXCHANGERATEDATE,T1.RECID,T2.ACCOUNTINGDATE,1,5637144576 FROM SOURCEDOCUMENTLINE T1 CROSS JOIN tempdb."DBO".t100010_A652A6A3D1EF4EE9A039F442E3BCEC58 T2 WHERE ((T1.PARTITION=5637144576) AND (T1.SOURCEDOCUMENTHEADER=5638078273)) AND ((T2.PARTITION=5637144576) AND (T2.SOURCEDOCUMENTLINE=T1.RECID))

Very interesting error.  Based on this blog post, it seems an AOS restart may fix the issue.  I will try it here shortly...

UPDATE:
AOS Restart did not fix the issue.... Continuing on...

UPDATE:
Not sure why, but creating a new time sheet did the trick.  Posted perfectly.