I'm trying to update Customer data in MS NAV 2017 using OData and PHP. I can read and create Customers using the /CustomerCard uri. But I can't get the update working (PATCH nor MERGE nor PUT). I try several combinations but with no success. I also already read a lot of threads, forums, etc.
When I want to do a PATCH on /Customer(No=XXXXXX), I get the error message : Resource not found for the segment 'Customer'.
But when I want to do a PATCH on /CustomerCard(No=XXXX), I get the error message : Bad Request - Error in query syntax.
And when I want to do a PATCH on /CustomerCard without parameters, I get the error message : 'PATCH' requests for 'Collection' are not supported by Microsoft Dynamics NAV OData web services.
I'm sending the ETag in the header. I tried with PATCH, MERGE and PUT. Same result.
Am I missing some configuration ?
Thanks for your help.
Here is my code.
$customernb = "R1500000";
$url1 = 'https://MYDOMAIN/ODatav4/CustomerCard';
$url2 = '?$filter=No%20eq%20%27';
$url3 = '%27';
$url = $url1.$url2.$customernb.$url3;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$username = "MYUSER";
$password = "MYPWD";
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
curl_close($ch);
$j = json_decode($result);
print_r($j);
// THIS WORKS FINE !
/*
* Update
*/
$newcustomer = new stdClass();
$newcustomer->Name = "OMEGA SHIRT UPDATED";
$newcustomer->Salesperson_Code = "JVP";
$newcustomer->Sales_Contact_Code = "TFS";
$etag = $j->value[0]->ETag;
$headeretag = $j->value[0]->{'@odata.etag'};
$newcustomer->ETag = $etag;
$newcustomer->{'@odata.etag'} = $headeretag;
$jsonDataEncoded = json_encode($newcustomer);
$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard('.$j->value[0]->No.')';
//$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard';
//$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard?$filter=No%20eq%20%27'.$j->value[0]->No.'%27';
$ch = curl_init($url5);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
//$encodedetag = "W/\"'".urlencode($etag)."'\"";
$encodedetag = $headeretag;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;If-Match: '.$encodedetag));
//$headers.Add("If-Match",'W/"' + "'" + [uri]::EscapeDataString($JToken.ETag.ToString()) + "'" + '"') #Etag Value
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
//CURLAUTH_NTLM
$result = curl_exec($ch);
print_r(json_decode($result));
I found the solution and will document it here for other developers. Here are the changes I made to my previous code:
So, to summarize, I fixed the URI and I fixed the HTTP Header. The rest was fine. Here is my new code:
$customernb = "R1500000";
$url1 = 'https://MYDOMAIN/ODatav4/CustomerCard';
$url2 = '(\'';
$url3 = '\')';
$url = $url1.$url2.$customernb.$url3;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$username = "MYUSER";
$password = "MYPWD";
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
curl_close($ch);
$j = json_decode($result);
print_r($j);
/*
* Update
*/
$newcustomer = new stdClass();
$newcustomer->Name = "OMEGA SHIRT UPDATED";
$newcustomer->Salesperson_Code = "JVP";
$newcustomer->Sales_Contact_Code = "TFS";
$etag = $j->value[0]->ETag;
$headeretag = $j->value[0]->{'@odata.etag'};
$jsonDataEncoded = json_encode($newcustomer);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
$encodedetag = $headeretag;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json','Content-Type: application/json','If-Match: '.$encodedetag));
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
print_r(json_decode($result));