php-shopify icon indicating copy to clipboard operation
php-shopify copied to clipboard

Fulfilled an order by creating new fulfillment

Open AntoineLHF opened this issue 2 years ago • 6 comments

Hello,

I try to develop a Symfony app in wich I would like to change the value of fulfillment_status for an order, from null to fulfilled. First of all, I tried :

$updateInfo = array (
        "fulfillment_status" => "fulfilled",
        "email"=>"[email protected]"
);
$res = $shopify->Order($orderId)->put($updateInfo);

But, even if the email field is updated as expected, the value of fulfillment_status doesn't changed.

I finally find that I have to manage fulfillment object to change the fulfillment_status of an order. I found some posts (#283 and #268 ) about how to update an existing fulfillment, but, in my case, fulfillment is null : "fulfillments" => []

So I tried to create one by this way :

$newFulfillment = [
    "order_id" => $orderId
];
$shopify->Fulfillment->post($newFulfillment);

But I get this error : The required line_items_by_fulfillment_order field is missing. And when I try :

$newFulfillment = array (
        "order_id" =>$orderId,
        "line_items_by_fulfillment_order" => [
            "fulfillment_order_id" => $orderId
          ],
       );

I get : line_items_by_fulfillment_order - expected Hash to be a Array

I suppose something wrong in the content-type, but I don't know hom to deal with this.

My init :

 $config = array(
      'ShopUrl' => $_ENV['SHOPIFY_APP_HOST_NAME'],
      'ApiKey' => $_ENV['SHOPIFY_API_KEY'],
      'AccessToken' => $_ENV['SHOPIFY_ACCESS_TOKEN'],
      'ApiVersion' => "2023-01",
);
ShopifySDK::config($config);
$shopify = new ShopifySDK($config);

AntoineLHF avatar Jan 13 '23 17:01 AntoineLHF

function postFulfillment($locid,$trackingnumber,$trackingcompany,$trackingurl,$config){
	global $config;
	$postdata = array (
		"location_id" => $locid,
		"tracking_number" => $trackingnumber,
		"tracking_company" => $trackingcompany,
		"tracking_url" => $trackingurl
	);
	fulfillOrder($orderid,$postdata,$config);
}

function fulfillOrder($orderid,$postdata,$config){
	$shopify = new PHPShopify\ShopifySDK($config);
	return $shopify->Order($orderid)->Fulfillment->post($postdata);
}

zamliyconsulting avatar Jan 13 '23 19:01 zamliyconsulting

Hi @zamliyconsulting Thank you for your reply, but I already get the message "The required line_items_by_fulfillment_order field is missing"

AntoineLHF avatar Jan 16 '23 09:01 AntoineLHF

Please check the latest release.

tareqtms avatar Feb 13 '23 03:02 tareqtms

@zamliyconsulting As I see in your postFulfillment function. fulfillOrder($orderid,$postdata,$config); But you don't have $orderid in your code. The way I do it is get the original order data, then create $fulfillment_order_line_items array and include it with the post data.

$params = array(
	'name' => $order_number,
);
$shopifyOrders = $shopify->Order->get($params);
if(isset($shopifyOrders[0]['id']))
{
	$shopifyOrder = $shopifyOrders[0];
	
	$fulfillment_order_line_items = array();
	
	foreach($shopifyOrder['line_items'] as $line_item)
	{
		$fulfillment_order_line_item = array();
		$fulfillment_order_line_item['id'] = $line_item['id'];
		$fulfillment_order_line_item['quantity'] = $line_item['quantity'];
		
		$fulfillment_order_line_items[] = $fulfillment_order_line_item;
	}
	
	$postInfo = array(
		"location_id" => $shopify_location_id,
		"tracking_number" => null,
		"tracking_urls" => [],
		"notify_customer" => true,
		"line_items_by_fulfillment_order" => array(
			"fulfillment_order_id" => $shopifyOrder['id'],
			"fulfillment_order_line_items" => $fulfillment_order_line_items,
		),
	);
				
	$shopify->Order($shopifyOrder['id'])->Fulfillment->post($postInfo);
}

Hope this will help.

PHPism avatar Feb 16 '23 14:02 PHPism

return $shopify->Order($orderid)->Fulfillment->post($postdata); $shopify->Order($orderid)->Fulfillment->post($postdata); Isn't this one Deprecated?

tonytoms avatar Feb 23 '23 04:02 tonytoms

The "line_items_by_fulfillment_order - expected Hash to be a Array" is due to how $newFulfillment is formatted. Try the below - where $item is the line_item in the FulfillmentOrder;

$newFulfillment = array(
	'location_id' => $item['assigned_location_id'],
	'tracking_number' => null,
	'notify_customer' => false,
	'line_items_by_fulfillment_order' => [
		array(
			'fulfillment_order_id' => $item['fulfillment_order_id'],
			'fulfillment_order_line_items' => [
				array(
					'id' => $item['id'],
					'quantity' => $item['quantity']
				)
			]
		)
	]
);

Here is a working code assuming you have your $order and $shopify objects. Note that you have to use the fulfillment_order_id as of API version 2022-07

if ($order['id']){
	//Get FulfillmentOrder
	$FulfillmentOrders = $shopify->Order($order['id'])->FulfillmentOrder()->get();
	if(!empty($FulfillmentOrders)){
		foreach($FulfillmentOrders as $FulfillmentOrder){
			foreach($FulfillmentOrder['line_items'] as $item){
				//Fulfill only items not yet fulfilled
				if($item['fulfillable_quantity'] > 0){
					try{
						$data = array(
							'location_id' => $item['assigned_location_id'],
							'tracking_number' => null,
							'notify_customer' => false,
							'line_items_by_fulfillment_order' => [
								array(
									'fulfillment_order_id' => $item['fulfillment_order_id'],
									'fulfillment_order_line_items' => [
										array(
											'id' => $item['id'],
											'quantity' => $item['quantity']
										)
									]
								)
							]
						);
						$Fulfillment = $shopify->Fulfillment->post($data);
					} catch(Exception $e) {
						echo 'Caught exception - Fulfillment Items: ' . $order['id'] . ' - ',  $e->getMessage(), "\n";
						continue;
					}
				}
			}
		}
	}
}

folz14 avatar Apr 04 '23 18:04 folz14