<?php
namespace App\Controller\Etl\Shopify;
use App\Entity\Customer;
use App\Entity\Hcp;
use App\Entity\Order;
use App\Service\OrderService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\Persistence\ManagerRegistry;
use PHPShopify\ShopifySDK;
use \DateTime;
use Exception;
use PHPShopify\Exception\ApiException;
use Symfony\Component\HttpFoundation\JsonResponse;
class OrderController extends AbstractController
{
/**
* Set fields to order object from an order data
*
* @param Order $object
* @param [type] $array
* @return void
*/
public function fromOrderArray(Order $object, Customer $customer, $array): Order
{
$paymentStatus = 'pending';
if (!empty($array['invoice_url'])){
$draftOrderLink = $array['invoice_url'];
}
$orderDate = date('Y-m-d H:i:s', strtotime($array['created_at']));
if ($array['status'] == 'completed'):
$paymentStatus = 'completed';
$draftOrderLink = '';
endif;
$object->setOrderId($array['id'])
->setDate(new DateTime($orderDate))
->setTotal($array['total_price'])
->setPaymentStatus($paymentStatus)
->setCustomer($customer)
->setDraftOrderLink($draftOrderLink)
;
if ($array['shipping_line']){
$object->setShippingCost($array['shipping_line']['price']);
} else {
$object->setShippingCost(0);
}
return $object;
}
public function createcustomerArr($request)
{
$customerArr = [
'first_name' => $request->get('first_name'),
'last_name' => $request->get('last_name'),
'email' => $request->get('email'),
'phone' => $request->get('mobile_number'),
'tags' => 'hcp-customer',
];
return $customerArr;
}
/**
* @Route("/draft_order", name="app_draft_order")
*/
public function index(ManagerRegistry $doctrine, OrderService $orderService): Response
{
$entityManager = $doctrine->getManager();
$config = array(
'ShopUrl' => 'solgar-nz.myshopify.com',
'AccessToken' => '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',
);
$shopify = new ShopifySDK($config);
$draftOrders = $shopify->DraftOrder->get([
'status' => 'completed',
'limit' => 100,
]);
if(!empty($draftOrders)):
foreach($draftOrders as $draftOrder):
if (str_contains($draftOrder['tags'], 'hcp-order')):
$draftOrderRecord = $entityManager->getRepository(Order::class)->findOneBy(array('orderId' => $draftOrder['id']));
if (empty($draftOrder) || empty($draftOrder['customer'])) {
continue;
}
$customer = $entityManager->getRepository(Customer::class)->findOneBy(array('customerId' => $draftOrder['customer']['id']));
if (empty($customer)) {
continue;
}
if (empty($draftOrderRecord)):
$draftOrderRecord = new Order();
endif;
$newOrder = $this->fromOrderArray($draftOrderRecord, $customer, $draftOrder);
// Delete the draftorder after updating order in database if order is completed
if ($draftOrder['status'] == 'completed'){
// Update link with new order url
$shopify->DraftOrder($draftOrder['id'])->delete();
// Remove order item as well
$orderItems = $newOrder->getOrderItems();
foreach ($orderItems as $orderItem) {
$entityManager->remove($orderItem);
}
$entityManager->remove($newOrder);
} else {
$entityManager->persist($newOrder);
}
$entityManager->flush();
endif;
endforeach;
endif;
$this->addFlash('success', 'Orders have been updated successfully.');
return new Response('Draft orders have been updated successfully.', 200);
}
/**
* @Route("/order", name="app_order")
*/
public function getOrder(ManagerRegistry $doctrine, OrderService $orderService): Response
{
$entityManager = $doctrine->getManager();
$config = array(
'ShopUrl' => 'solgar-nz.myshopify.com',
'AccessToken' => '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',
);
// get from date
$today = new DateTime('yesterday');
$fromDate = $today->format('Y-m-d\T00:00:00-00:00');
$shopify = new ShopifySDK($config);
$orders = $shopify->Order->get([
// 'tags' => 'hcp-order',
'created_at_min' => $fromDate
]);
if(!empty($orders)):
foreach($orders as $order):
if (empty($order['customer'])){
continue;
}
$orderRecord = $entityManager->getRepository(Order::class)->findOneBy(array('orderId' => $order['id']));
$customerRecord = $entityManager->getRepository(Customer::class)->findOneBy(array('customerId' => $order['customer']['id']));
if (empty($orderRecord)){
$orderRecord = new Order();
} else {
continue;
}
$orderDate = date('Y-m-d H:i:s', strtotime($order['created_at']));
$paymentStatus = 'completed';
if (str_contains($order['tags'], 'hcp-order')):
$orderRecord->setOrderId($order['id'])
->setDate(new DateTime($orderDate))
->setTotal($order['total_price'])
->setPaymentStatus($paymentStatus)
->setCustomer($customerRecord)
;
if($order['shipping_lines']) {
$orderRecord->setShippingCost($order['shipping_lines'][0]['price']);
} else {
$orderRecord->setShippingCost(0);
}
if ($customerRecord) {
if ($customerRecord->getHcp()) {
$orderRecord->setHcp($customerRecord->getHcp());
}
}
$entityManager->persist($orderRecord);
$entityManager->flush();
$orderService->pushProductsFromOrder($orderRecord->getOrderId());
else: // Independent order e.g. reorder from customers
$newLineItems = $orderService->getHcpItems($order['line_items']);
if ($newLineItems){ // If there is an HCP product then do below
$orderRecord->setOrderId($order['id'])
->setDate(new DateTime($orderDate))
->setTotal($order['total_price'])
->setPaymentStatus($paymentStatus)
->setCustomer($customerRecord)
;
if ($customerRecord) {
if ($customerRecord->getHcp()) {
$orderRecord->setHcp($customerRecord->getHcp());
}
}
$newOrderTotal = 0;
foreach($newLineItems as $newItem) {
$newOrderTotal += $newItem->getPrice();
$newItem->setOrderParent($orderRecord);
$entityManager->persist($newItem);
}
$orderRecord->setTotal($newOrderTotal);
$entityManager->persist($orderRecord);
$entityManager->flush();
}
endif;
endforeach;
endif;
return new Response('Orders have been updated successfully.', 200);
}
/**
* Get customer from Shopify API with email address
*
* @param [String] $email
* @return Array
*/
public function getCustomerFromEmail($email)
{
$config = array(
'ShopUrl' => 'solgar-nz.myshopify.com',
'AccessToken' => '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',
);
$shopify = new ShopifySDK($config);
// Get customer records from hcp id
$customerObj = $shopify->Customer()->search([
"query" => "email:".$email
]);
if (empty($customerObj)) {
return $customerObj;
}
$response = $customerObj[0];
foreach($customerObj as $customer) {
if ($customer['email'] == $email) {
return $customer;
}
}
return $response;
}
/**
* @Route("/order/create_order", name="app_create_order")
*/
public function createOrder(ManagerRegistry $doctrine, Request $request, OrderService $orderService): Response
{
$entityManager = $doctrine->getManager();
$config = array(
'ShopUrl' => 'solgar-nz.myshopify.com',
'AccessToken' => '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',
);
$shopify = new ShopifySDK($config);
// GET request data
$customerData = $request->request;
$customerEmail = $customerData->get('email');
$customerNotes = $customerData->get('notes');
$orders = $customerData->get('orders');
if (empty($orders)) {
return new Response('Please add at least 1 product into order', 500);
}
if (empty($customerEmail)) {
return new Response('Please fill in patient\'s email', 500);
}
$customer = $entityManager->getRepository(Customer::class)->findOneBy(array('email' => $customerEmail)); // Check if email exists in customer table
// Set Hcp id to customer
$hcp_id = $customerData->get('hcp_id');
$hcp = $entityManager->getRepository(Hcp::class)->findOneBy(array('hcpId' => $hcp_id));
$isDraftOrderSent = true;
$shopifyCustomerObj = $this->getCustomerFromEmail($customerEmail);
if(empty($customer)) {
if (!$shopifyCustomerObj) {
$isDraftOrderSent = false;
$customerArr = $this->createcustomerArr($customerData);
// try catch api exception
try {
$customerObject = $shopify->Customer->post($customerArr);
} catch (ApiException $e) {
if (str_contains($e->getMessage(), '500 Internal Server Error' )) {
return new Response('Server Error', 500);
}
return new Response($e->getMessage(), 500);
}
$customer = new Customer();
$customer->setName($customerObject['first_name'] .' '. $customerObject['last_name']);
$customer->setCustomerId($customerObject['id']);
$customer->setEmail($customerObject['email']);
$customerObject = $shopify->Customer($customerObject['id'])->send_invite(
[
"from" => "Solgar NZ<[email protected]>",
"subject" => "Finalise Your Solgar Order",
"custom_message" => "<p>An order for Solgar products has been initiated by your HCP.
Use the link below to activate your account and complete the purchase.<br>
If you believe there is an error, please contact your HCP (".$hcp->getName().")
or Solgar Customer Assistance at <a href=\"tel:+6495252355\">+649 525 2355</a>.</p>"
]
);
} else {
// $firstCustomerObj = $shopifyCustomerObj[0];
if (str_contains($shopifyCustomerObj['tags'], 'HCP')) {
$shopify->Customer($shopifyCustomerObj['id'])->put(['tags' => 'HCP, hcp-customer']);
} else {
$shopify->Customer($shopifyCustomerObj['id'])->put(['tags' => 'hcp-customer']);
}
$customer = new Customer();
$customer->setName($shopifyCustomerObj['first_name'] .' '. $shopifyCustomerObj['last_name']);
$customer->setCustomerId($shopifyCustomerObj['id']);
$customer->setEmail($shopifyCustomerObj['email']);
}
}
$customer->setHcp($hcp);
// Persist customer to database
$entityManager->persist($customer);
$entityManager->flush();
// Time to create draft order
$lineItems = array();
foreach($orders as $order) {
array_push($lineItems, [
"variant_id" => $order['variantId'],
"quantity" => $order['quantity'],
]);
}
$draftOrderData = array (
"line_items" => $lineItems,
"tags" => "hcp-order",
"note" => $customerNotes,
"customer" => [
"id" => $customer->getCustomerId(),
]
);
try {
$draftOrderObject = $shopify->DraftOrder->post($draftOrderData);
} catch(ApiException $e) {
return new Response($e->getMessage(), 500);
}
$orderId = 0;
// Create Order obj on database
if (!empty($draftOrderObject)) {
$orderId = $draftOrderObject['id'];
$orderObj = new Order();
$newOrder = $this->fromOrderArray($orderObj, $customer, $draftOrderObject);
$newOrder->setHcp($hcp);
// Persist order to database
$entityManager->persist($newOrder);
$entityManager->flush();
// grab product items after order
try {
$response = $orderService->pushProductsFromDraftOrder($orderId);
} catch(Exception $e) {
return new Response($e->getMessage(), 500);
}
}
// Send email process
if ($isDraftOrderSent){
// Send email to customer for the order invoice.
$data = ["draft_order_invoice" => [
"to" => $customerEmail,
"from" => "Solgar NZ<[email protected]>",
"bcc" => [],
"subject" => "Finalise Your Solgar Order",
"custom_message" => "<p>An order for Solgar products has been initiated by your HCP.
Use the link below to complete the purchase and make a payment.<br>
If you believe there is an error, please contact your HCP (".$hcp->getName().")
or Solgar Customer Assistance at <a href=\"tel:+6495252355\">+649 525 2355</a>.</p>"
]
];
try {
$draftorder = $shopify->DraftOrder($orderId)->send_invoice($data);
}
catch( ApiException $e) {
if (str_contains($e->getMessage(), '500 Internal Server Error' )) {
return new Response('Server Error', 500);
}
return new Response($e->getMessage(), 500);
}
}
return new Response('The draft order has been created', 200);
}
/**
* @Route("/order/testing", name="app_create_order_testing")
*/
public function testing(ManagerRegistry $doctrine, Request $request, OrderService $orderService): Response
{
$entityManager = $doctrine->getManager();
$config = array(
'ShopUrl' => 'solgar-nz.myshopify.com',
'AccessToken' => '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',
);
$shopify = new ShopifySDK($config);
$data = ["draft_order_invoice" => [
"to" => '[email protected]',
"from" => "Solgar NZ<[email protected]>",
"bcc" => [],
"subject" => "Finalise Your Solgar Order",
"custom_message" => "<p>An order for Solgar products has been initiated by your HCP.
Use the link below to complete the purchase and make a payment.<br>
If you believe there is an error, please contact your HCP"
]
];
try {
$draftorder = $shopify->DraftOrder('1099155570921')->send_invoice($data);
}
catch( ApiException $e) {
if (str_contains($e->getMessage(), '500 Internal Server Error' )) {
return new Response('Server Error', 500);
}
return new Response($e->getMessage(), 500);
}
return new Response('The draft order has been created', 200);
}
}