Magento 2 Rest API Order edit - rest

I'm trying to figure out how to edit an order after I requested it.
I made a custom attribute whether an order is exported or not.
I first get all orders with status not exported and after I exported them, I want to change the custom attribute to exported.
What is the REST request to edit/update an order? I keep getting error messages like:
{"message":"%fieldName is a required field.","parameters":
{"fieldName":"entity"}
This is my code:
$json = array(
"entity_id" => $id,
"extension_attributes" => array(
"custom_export_attribute" => "exported",
)
);
$webapi = new ApiClient('https://dev.local.nl', self::$username, self::$password);
$response = $webapi->getClient()->request('PUT', '/rest/V1/orders/create', [
'headers' => [
'Authorization' => "Bearer " . $webapi->getToken(),
'Content-Type' => "application/json"
],
'body' => json_encode($json)
]);
return json_decode($response->getBody(), true);
I also tried:
$webapi->getClient()->request('PUT', '/rest/V1/orders/'.$id,

To edit / update order details, the Magento 2 /V1/orders accepts POST request method. As per Magento 2 Dev Doc, it accepts the request body in below format (You can find whole JSON request in documentation page):
{
"entity": {
"entity_id": 0,
"extension_attributes": {
}
}
}
So, you just need to update the $json variable as:
$json = [
"entity"=> [
"entity_id" => $id,
"extension_attributes" => [
"custom_export_attribute" => "exported"
]
]
]
And than invoke with POST request method instead of PUT. In my suggestion prefer to use Create API for new order creation.

Related

Adding solines to acumatica using rest Api

Am trying to create a sales order in acumatica using rest API with more than one soline but am able to create only one soline, below see my code
I would like to create one sales order with all cart items as solines for that particular sales order in acumatica.
if (isset($_SESSION['cart'])) {
foreach($_SESSION['cart'] as $row) {
if ($row['qty'] != 0) {
$product = $row['product'];
echo $product.
"<br>";
curl_setopt_array($curl, array(
CURLOPT_URL => "https://xxxxxxx.com/myinstance/entity/PLUS/17.200.001/SalesOrder",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_COOKIESESSION => 1,
CURLOPT_COOKIEFILE => $temp_data,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => "{\r\n \"OrderType\" : {value : \"SO\" } ,\r\n \"CustomerID\" : {value : \"C000000002\" },\r\n \"webItems\" : {value : \"$product\" },\r\n\"webQty\" : {value : \"1\" },\r\n\"WebTaxCat\" : {value : \"TAXABLE\" },\r\n}",
CURLOPT_HTTPHEADER => array("cache-control: no-cache", "content-type: application/json", "postman-token: 5248821b-91e9-5800-bd9c-b4c9775c6c5a"),
));
$response = curl_exec($curl);
$err = curl_error($curl);
if ($err) {
echo "cURL Error #:".$err;
} else {
echo $response;
}
}
}
}
Looking at your code you seems to have created your own endpoint or extended the default endpoint.
Though looking at the structure of the body that you are passing through the detail information seems to be on the same level as the top level entity.
If you created your own endpoint from scratch, I would recommend that you take a look at the Sales Order entity from default endpoint and its Details sub entity.
As normally, you should have a details object inside of the Sales Order node that can contain an array of details information.
If I was using the default endpoint I could pass the following JSON body to the address :
localhost/191u03/entity/Default/18.200.001/SalesOrder
{
"CustomerID": {"value": "ABARTENDE"},
"Details":
[
{
"InventoryID": {"value": "AACOMPUT01"},
"OrderQty": {"value": 5}
},
{
"InventoryID": {"value": "AALEGO500"},
"OrderQty": {"value": 50}
}
]
}
This will create a Sales Order with 2 So Lines.
Though if you want to add more line to an existing order then you should only need to mention the key fields of the top level entity and then the details information that you would want to add.
In the case of the Sales Order, the key fields are the OrderType and the OrderNbr.
If you have the time, I would recommend that you take a look at the Acumatica help website section about working with the contract based API: https://help-2019r1.acumatica.com/(W(5))/Help?ScreenId=ShowWiki&pageid=1c767ad9-da6d-4047-bc93-6970ad469504

guzzle 6 post does not work

I am trying to submit a post with JSON content. I always get this message back:
"Client
error: POST
https://sandbox-api-ca.metrc.com//strains/v1/create?licenseNumber=CML17-0000001
resulted in a 400 Bad Request response: {"Message":"No data was
submitted."}"
(All keys and license number are sandbox. I changed keys slightly so auth wont work. )
here is my code
public function metrc()
{
$client = new Client();
$url = 'https://sandbox-api-ca.metrc.com//strains/v1/create?licenseNumber=CML17-0000001';
$request = $client->post($url, [
'headers' => ['Content-Type' => 'application/json'],
'json' => ['name' => "Spring Hill Kush"],
'auth' => ['kH-qsC1oJPzQnyWMrXjw0EQh812jHOX52ALfUIm-dyE3Wy0h', 'fusVbe4Yv6W1DGNuxKNhByXU6RO6jSUPcbRCoRDD98VNXc4D'],
]);
}
Your code is correct, it should works as expected. Seems that the issue is on the server side. Maybe the format of the POST request is not correct?
BTW, 'headers' => ['Content-Type' => 'application/json'] is unnecessary, Guzzle sets the header by itself automatically when you use json option.

How can I do multipart requests mith Mojo::UserAgent?

I'd like to perform a multipart file upload to Google Drive as described here using a Mojo::UserAgent. I currently do it like this:
my $url = Mojo::URL->new('https://www.googleapis.com/upload/drive/v3/files');
$url->query({ fields => 'id,parents',
ocr => 'true',
ocrLanguage => 'de',
uploadType => 'multipart' });
my $tx = $ua->post($url,
json => { parents => [ '0ByFk4UawESNUX1Bwak1Ka1lwVE0' ] },
{
'Content-Type' => 'multipart/related',
'parents' => [ '0ByFk4UawESNUX1Bwak1Ka1lwVE0' ]
},
$content );
but it doesn't work.
I've managed authorization OK (omitted here) and simple file upload works fine. I just can't seem to do the multipart.
I've tried to make sense of the docs here - but to no avail, in the sense that the file gets uploaded OK, but the JSON part gets ignored, and the file gets uploaded in the root folder.

File Upload in Rest API yii2

my controller file inside api/v1/controller/
class ProfileController extends ActiveController
{
public $modelClass = 'app\models\Profile';
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' =>
['index', 'view', 'createnew','update','search'],
'formats' =>
['application/json' => Response::FORMAT_JSON,],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'createnew' => ['post'],
'update' => ['put'],
'delete' => ['delete'],
'deleteall' => ['post'],
'search' => ['get']
],
]
];
}
public function actionCreatenew() {
$model = new Profile();
$model->load(Yii::$app->request->post());
$model->asset = UploadedFile::getInstance($model, 'asset');
$name = $model->user_id;
if($model->asset) {
$model->asset->saveAs('uploads/'.$name.'.
'.$model->asset->extension);
$model->asset = $model->asset->name.'.'.
$model->asset->extension;
}
if($model->save()) {
echo json_encode(array('status'=>"Success",
'data'=>$model->attributes),JSON_PRETTY_PRINT);
} else {
echo json_encode(array('status'=>"Failure",
'error_code'=>400,
'errors'=>$model->errors),JSON_PRETTY_PRINT);
}
}
}
When I try to use access this from Postman like:
POST http://localhost/myapp/api/v1/profiles
I get Invalid Parameter – yii\base\InvalidParamException
Response content must not be an array.
What is the issue?? help would be grateful!! Thanks
You can easily receive single / multi-uploaded files using HTTP POST with form-data encoding in Yii2, directly in your Yii2 Controller / action.
Use this code:
$uploads = UploadedFile::getInstancesByName("upfile");
if (empty($uploads)){
return "Must upload at least 1 file in upfile form-data POST";
}
// $uploads now contains 1 or more UploadedFile instances
$savedfiles = [];
foreach ($uploads as $file){
$path = //Generate your save file path here;
$file->saveAs($path); //Your uploaded file is saved, you can process it further from here
}
If you use Postman API client to test how your API is working, you can configure the upload endpoint to work like this for multi-file uploads:
Note: The upfile[] square brackets are important! Postman will happily let you select multiple files for upload in one slot, but this will not actually work. Doing it the way shown in the screenshot makes an array of files available to the Yii2 action, through the UploadedFile mechanism. This is roughly equivalent to the standard PHP $_FILES superglobal variable but with easier handling.
Single files can be uploaded with or without the [] square brackets after the key name. And of course you can name upfile whatever you like, for your convention.
You should use \yii\web\UploadedFile::getInstanceByName('asset'); instead of getInstance() checkout this Link

OneDrive REST API error 400 when creating folder

I have a problem when trying to create a folder in my OneDrive using the REST API. I'm using following documentation page https://dev.onedrive.com/items/create.htm. I have successfully authenticated and the token is working ok on other endpoints.
I spent now over a day trying every possible URI/method combination on this one but with no success. All other endpoints (directory listing etc.) are OK, just this one is driving me crazy.
If anyone could point me to the error in my approach, any help would be appreciated.
The code below returns error 400 with following message:
{"error":{"code":"invalidRequest","message":"The request is malformed or incorrect."}}
I'm using GuzzlePhp library for the request handling. My code (simplified):
$parentId = '01WZZ7ZY2LNHB75JADQJD3GGUQFSCRRZTQ'; //id to root
$method = "POST";
//none of these does the trick (to be clear, I use only one at the time)
$url = '/_api/v2.0/drive/items/'.$parentId.'/NewFolder'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //post
$url = '/_api/v2.0/drive/root:/NewFolder'; //post
$options = [
'headers' => [
'Authorization' => $token,
'Content-Type' => 'application/json',
'Content-Length'=> 0,
]
'form_params' => [
"name" => "NewFolder",
"folder" => (object)[],
"#name.conflictBehavior" => "fail"
]
];
//Guzzle library sends the code as specified
$res = $this->client->request($method, $url, $options);
The OneDrive API doesn't support form post semantics - the parameters are expected in the body as a JSON encoded blob. I haven't used Guzzle, but something like this should work:
$parentId = '01WZZ7ZY2LNHB75JADQJD3GGUQFSCRRZTQ'; //id to root
$method = "POST";
//none of these does the trick (to be clear, I use only one at the time)
$url = '/_api/v2.0/drive/items/'.$parentId.'/NewFolder'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //post
$url = '/_api/v2.0/drive/root:/NewFolder'; //post
$options = [
'headers' => [
'Authorization' => $token,
'Content-Type' => 'application/json',
'Content-Length'=> 0,
]
'body' =>
'{
"name": "NewFolder",
"folder": { },
"#name.conflictBehavior": "fail"
}'
];
//Guzzle library sends the code as specified
$res = $this->client->request($method, $url, $options);