A bug or a feature? Sometimes it’s hard to tell for sure.
Web services are a fantastic tool in NAV, however, they do not always behave exactly as you would expect them to. There is one particularly annoying behavior, which just after you get used to it starts getting even stranger.
So, setting any numeric value during the Create method call on any page web service will have no effect, and the only way to set a value in a numeric field would be through a subsequent call to Update method.
I know I promised I wouldn’t write code here in my blog, but this post simply wouldn’t work without it. So, expose Page 253 Sales Journal as a web service, and then try this simple code:
SalesJournal_Service srv = new SalesJournal_Service(); <br />SalesJournal jnl = new SalesJournal(); <br />jnl.Posting_Date = DateTime.Now.Date; <br />jnl.Account_Type = Account_Type.G_L_Account; <br />jnl.Account_No = "7150"; <br />jnl.Document_Type = Document_Type.Invoice; <br />jnl.Document_No = "TEST123"; <br />jnl.Amount = 1000; <br />srv.Create("DEFAULT", ref jnl);
When you execute that, this is what you get in NAV:
Take a look at the Amount field. It’s zero, even though I explicitly set to 1000. Also, notice that Document Type is empty, even though I actually set it to Invoice. Yes – options are numeric, and they exhibit exactly the same stubbornness in Web services.
Now, change the code slightly:
jnl.Posting_Date = DateTime.Now.Date; <br />srv.Create("DEFAULT", ref jnl); <br />jnl.Account_Type = Account_Type.G_L_Account; <br />jnl.Account_No = "7150"; <br />jnl.Document_Type = Document_Type.Invoice; <br />jnl.Document_No = "TEST123"; <br />jnl.Amount = 1000; <br />srv.Update("DEFAULT", ref jnl);
Give it some runtime, and your NAV will show this:
Funny. Now both Document Type and Amount have correct values.
And this is precisely how any page Web services, standard or custom, behaves when you set numeric fields during the initial Create call.
If you think this is not a big deal, and you just go and do a Create followed up by an Update, that’s precisely what I thought until a couple of days ago. However, the problem is big. Big time big.
Guess what happens if your primary key contains a numeric value? Precisely! It will be reset to 0. Actually, the only way for a page web service to set a correct primary key numeric value during the Create call is to have AutoSplitKey property set to true, or to have a built-in filter on the numeric field (e.g. Sales Order).
If you don’t have such a filter, and you need to set the numeric value directly, then you’ll have issues. If you are lucky enough that you don’t need 0 as a value in any of the records, then you can create it, and immediately update it, which would result in an expensive rename operation in NAV, but still the job gets done. If you are not lucky, and the 0 is already there in a record, you may get primary key violation and not be able to insert the record at all.
And what if, just what if the table itself prevented renaming? Such as, for example, Default Dimension? Well, yes, sorry but you can’t use that web service.
Of course, there is a workaround: you can create a codeunit, have a function there which inserts the record for you. This would work. However, this will cause issues with transaction integrity, because the call to this function would be executed in a separate transaction. You could expose this codeunit as an extension codeunit, ensuring the transaction integrity, however you would end up using too many extension codeunits which do nothing but fix a bug, each.
I don’t know if there is a better workaround or a solution to this, but from what I’ve done so far with web services, I’d say no. If you have a solution, or a workaround, which works better than this one suggested above, please share it here.