I'm testing out some electronic signatures. I've got the signature system to prompt correctly when a field in a form is updated but when I update() or insert() a field directly into a table via x++ nothing seems to happen. From the formdatasource the stack indicated that the singature code runs form the super() call in the validatewrite on the datasource.
Does anyone know what methods or actions need to be taken via x++ to trigger the electronic signature?
In addition to André's suggestion, I would also add that the validateWrite() method isn't called automatically when you're updating a record from X++. You could add something like this to your code:
That should trigger the super() call in validateWrite() for you.
I think I overlooked something in your question. I had a similar issue about a year ago. It is very hard to understand how and where to call the signature from x++ code manually. Also if you have the signature, how to store everything so AX thinks it is signed correctly.
When you are using a form datasource, the signature will be prompted. If you are using a variable to fill/modifty a table it will not be called, but you then get the error "Transaction does not contain a required signature".
We solved it by using a form datasource and interact with this one. This prevented us for deeply looking into this signature framework.
André Arnaud de Calavon | Microsoft Dynamics AX Solution architect | My blog | My company
This post is my own opinion and does not necessarily reflect the opinion or view of my company, Microsoft, both its employees, or other MVPs.
I've played with this today and used the formdatasource to update the table. This got me to the signature process but I hit a bug in /classes/SIGBaseDocument.value2str() line 47 (“wrong argument type for function”). I think it can’t understand how to interpret the pdf object in the container. I can comment this line out and it all works but given this is deep down leaving this commented out is bad news.
Anyway, this is actually one of the problems I was running into in my original table update method so I think I did actually get it to work outside of the form data source. So for anyone looking at this in the future (and not working with a pdf in a container) I think this would work for you:
When you want to write your change to the table (in this case called reportTable)...
The validate write method...
public boolean validateWrite()
Info info = new info();
ret = super();
ret = info.collectESignature(DatabaseLogType::Update, this);
You'd want to have a condition in there to determine the correct databaselogtype (update or insert) to sent to the collectESignature() method but this would be straight forward. If the bug wasn't there I think this would work fairly well.
Thanks Justin for contributing to this answer too.
I have checked the code used to disable the Signature when writing from x++ to the database. It is indeed the SkipDatabaseLog method.
When changing the field itself, the electronic signature is not triggered. It is triggered when a write action to the database is called. (insert, update or delete).
Normally the electronic signature will be triggered then automatically. It is possible to use a x++ statement to disable the call of this logic per table. I can't recall the method, but think it was the table.skipDatabaseLog() method.
Did you use a statement like table.skip...[something]?
Also another question: did you use a build in signature or a custom on a table?
Thanks for your response. I'm not using any 'skip' type statements. Its a custom table with a container field that I'm updating. I've got a custom signature requirement setup on this field. The code is simply
I also tried doupdate() without any luck. Perhaps I need to setup some table properties? I'll compare against a table which is working for signatures.
I'm also getting "Transaction does not contain a required signature" error...
That makes sense. I've tried calling the validatewrite(). Even though it is running this command it doesn't seem to be getting to the signature code.
I think I may need to make a call to info.collectESignature(...
I'm fried for today but I'll test it out tomorrow.
Thanks for sharing your findings.
Just finishing this off, I did a bit more testing today and confirmed (at least well enough for now) that it is the file in the container that causes the run time issue with the strfmt. Putting a string or int in the container causes no issues and signs the change happily. This bit of code may not be that critical to the process of signing but I'm not really game to play around with code down at this level to avoid the bug - particularly for legal / compliance related functions (see bottom of msdn.microsoft.com/.../cc589558.aspx)
Perhaps this is a bug which is fixed in a newer release. Moving onto something else now.
..and finally this was interesting
I'm facing same error message "Transaction does not contain a required signature" when cheque status is updated to paid while generating AP payment.
I tried to call info.collectESignature() in validateWrite method but I'm getting another error "Cannot create a signature: already in a transaction (level 2)."
In standard, we cannot save the record until electronic signature is completed.
Might have to change standard code so my ttslevel is 0 before calling validateWrite() and info.collectESignature()