<?php
/**
 * Manage Color Swatches
 *
 * PHP version 5.6
 *
 * @category  Settings
 * @package   Eloquent
 * @author    Sanjeeb Dakhinaray <steve@imprintnext.com>
 * @copyright 2021-2022 Riaxe Systems
 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
 * @link      http://inkxe-v10.inkxe.io/xetool/admin
 */

namespace App\Modules\Integration\Controllers;

use App\Components\Controllers\Component as ParentController;
use App\Modules\Integration\Models\PluginSettings;
use App\Modules\Customers\Controllers\CustomersController;
use App\Modules\Products\Controllers\ProductsController;
use App\Modules\Quotations\Models\ProductionQuickbooksRelation;
use App\Modules\Orders\Controllers\OrdersController;
use App\Modules\PurchaseOrder\Controllers\PurchaseOrderController;

class QuickBookController extends ParentController  {
    private $clientId;
    private $clientSecret;

    /**
     * HTTP Methods
     */
    const HTTP_METHOD_GET    = 'GET';
    const HTTP_METHOD_POST   = 'POST';
    const HTTP_METHOD_PUT    = 'PUT';
    const HTTP_METHOD_DELETE = 'DELETE';
    const HTTP_METHOD_HEAD   = 'HEAD';
    const HTTP_METHOD_PATCH   = 'PATCH';

    public function __construct()
    {
        $this->clientId     = QUICKBOOK_CLIENT_ID;
        $this->clientSecret = QUICKBOOK_CLIENT_SECRET; 
    }

    public function callForOpenIDEndpoint($access_token, $url){
      $authorizationHeaderInfo = $this->generateAccessTokenHeader($access_token);
      $http_header = array(
        'Accept' => 'application/json',
        'Authorization' => $authorizationHeaderInfo
      );
      return $this->executeRequest($url , null, $http_header, self::HTTP_METHOD_GET);
    }

    private function generateAccessTokenHeader($access_token){
        return 'Bearer ' . $access_token;
    }


    public function getAuthorizationURL($authorizationRequestUrl, $scope, $redirect_uri, $response_type, $state){
        $parameters = array(
          'client_id' => $this->clientId,
          'scope' => $scope,
          'redirect_uri' => $redirect_uri,
          'response_type' => $response_type,
          'state' => $state
          //The include_granted_scope is always set to false. No need to pass.
          //'include_granted_scope' => $include_granted_scope
        );
        $authorizationRequestUrl .= '?' . http_build_query($parameters, null, '&', PHP_QUERY_RFC1738);
        return $authorizationRequestUrl;
    }

    public function getAccessToken($tokenEndPointUrl, $code, $redirectUrl, $grant_type){
       if(!isset($grant_type)){
          throw new InvalidArgumentException('The grant_type is mandatory.', InvalidArgumentException::INVALID_GRANT_TYPE);
       }
       $authorizationHeaderInfo = $this->generateAuthorizationHeader();
       $parameters = array(
         'grant_type' => $grant_type,
         'code' => $code,
         'redirect_uri' => $redirectUrl
       );
       $http_header = array(
         'Accept' => 'application/json',
         'Authorization' => $authorizationHeaderInfo,
         'Content-Type' => 'application/x-www-form-urlencoded'
       );

       //Try catch???
       return $this->executeRequest($tokenEndPointUrl , $http_header, self::HTTP_METHOD_POST, $parameters);
    }

    /**
     * Generate Refresh Access Token. 
     *
     * @param $tokenEndPointUrl  Slim's Request object
     * @param $grant_type Grant type
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */
    public function refreshAccessToken($tokenEndPointUrl, $grant_type){
        $pluginsObj = new PluginSettings();
        $checkRecord = $pluginsObj->where(
            ['catalog_code' => 'quickbooks']
        );
        $checkRecord = $checkRecord->first();
        $checkRecord = json_clean_decode($checkRecord['settings']);
        $refreshToken = $checkRecord['refresh_token'];
        $parameters = array(
            'grant_type' => $grant_type,
            'refresh_token' => $refreshToken
        );
        $authorizationHeaderInfo = $this->generateAuthorizationHeader();
        $http_header = array(
            'Accept' => 'application/json',
            'Authorization' => $authorizationHeaderInfo,
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $result = $this->executeRequest($tokenEndPointUrl , $http_header, self::HTTP_METHOD_POST, $parameters);
        if(isset($result['access_token'])) {
            $pluginData = [
            'catalog_code' => $checkRecord['catalog_code'],
            'domain_imprint_path' => $checkRecord['domain_imprint_path'],
            'auth_code' => $checkRecord['auth_code'],
            'access_token' => $result['access_token'],
            'expires_at' => $result['expires_in'],
            'refresh_token' => $result['refresh_token'],
            'x_refresh_token_expires_in' => $result['x_refresh_token_expires_in'],
            'token_type' => $result['token_type'],
            'expires_in' => $result['expires_in'],
            'realmid' => $checkRecord['realmid'],
            ];
            $pluginSettingData['settings'] = json_encode($pluginData,true);
            $pluginsObj = new PluginSettings();
            $pluginsObj->where(['catalog_code' => 'quickbooks'])->update($pluginSettingData);
        }      
        return $result;
    }

    private function generateAuthorizationHeader(){
        $encodedClientIDClientSecrets = base64_encode($this->clientId . ':' . $this->clientSecret);
        return 'Basic ' . $encodedClientIDClientSecrets;
        
    }

    /**
     * Generate Refresh Access Token. 
     *
     * @param $curl_options  Curl Parameter
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */
    private function quickbookCurl($curl_options){
        $ch = curl_init();
        curl_setopt_array($ch, $curl_options);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //Execute the Curl Request
        $result = curl_exec($ch);    
        curl_getinfo($ch, CURLINFO_HEADER_OUT );
        curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        if ($curl_error = curl_error($ch)) {
            throw new Exception($curl_error);
        }else {
            $json_decode = json_decode($result, true);
        }
        curl_close($ch);
        return $json_decode;
    }
    /**
     * Generate Refresh Access Token. 
     *
     * @param $url  Slim's Request object
     * @param $parameters Api endpoint
     * @param $http_header Header parameter for curl. 
     * @param $http_method Http method for curl
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */
    private function executeRequest($url, $http_header, $http_method, $parameters = array()){
        $pluginsObj = new PluginSettings();
        $checkRecord = $pluginsObj->where(
            ['catalog_code' => 'quickbooks']
        );
        $checkRecord = $checkRecord->first();
        $checkRecord = json_clean_decode($checkRecord['settings']);
        $accessToken = $checkRecord['access_token'];
        if(!isset($http_header['Authorization'])){
            $http_header['Authorization'] = "Bearer ". $accessToken;
        }
        $urlTest = explode("https://",$url);
        if(sizeof($urlTest) == 1) {
            //Concat API Endpoint url with path
        $url = QUICKBOOK_TOKEN_END_POINT_URL.'v3/company/'.$checkRecord['realmid'].$url;
        }
        $curl_options = array();
        switch($http_method){
            case self::HTTP_METHOD_GET:
                $curl_options[CURLOPT_HTTPGET] = 'true';
              if (is_array($parameters) && count($parameters) > 0) {
                $url .= '?' . http_build_query($parameters);
              } else {
                $url .= '?' . $parameters;
              }
              break;
            case self:: HTTP_METHOD_POST:
              $curl_options[CURLOPT_POST] = '1';
              if(is_array($parameters) && count($parameters) > 0){
                $body = http_build_query($parameters);
                $curl_options[CURLOPT_POSTFIELDS] = $body;
              }
              else {
                $body = $parameters;
                $curl_options[CURLOPT_POSTFIELDS] = $body;
              }
              break;
              default:
              break;
        }
        if(is_array($http_header)){
            $header = array();
            foreach($http_header as $key => $value) {
                $header[] = "$key: $value";
            }
            $curl_options[CURLOPT_HTTPHEADER] = $header;
        }
        $curl_options[CURLOPT_URL] = $url;
        $result = $this->quickbookCurl($curl_options); 
        if(!empty($result['fault']) && !empty($result['fault']['error']) ){
            $response = $this->refreshAccessToken(QUICKBOOK_TOKEN_EX_URL,'refresh_token');
            $accessToken = $response['access_token'];
            $header[2] =  'Authorization: '."Bearer ". $accessToken;
            $curl_options[CURLOPT_HTTPHEADER] = $header;
            $result = $this->quickbookCurl($curl_options);

        }
        return $result;
    }


    /**
     * Create Customer
     *
     * @param $allPostPutVars  Parameters of customers
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return int
     */
    public function quickbookCustomerCreate($allPostPutVars){
        $emailAddress = $allPostPutVars['DisplayName'];
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $queryPath = '/query';
        $queryParameters = array(
            'query' => "select * from Customer Where DisplayName = '".$emailAddress."'",
            'minorversion' => 63
        );
        $result = $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $queryParameters);
        if(!empty($result['QueryResponse']['Customer'])){
           $customerId = $result['QueryResponse']['Customer'][0]['Id'];
        }
        else {
            $path = '/customer?minorversion=63';
            $parameters = json_encode($allPostPutVars,true);
            $this->generateAuthorizationHeader();
            $http_header = array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json'
            );
            $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
            $customerId = $result['Customer']['Id'];
        }
        if($customerId) {
            return $customerId;
        }
    }

    /**
     * Get Account detail of Quickbook
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */
    public function getAccount(){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $queryPath = '/query';
        $queryParameters = array(
            'query' => "select * from Account",
            'minorversion' => 63
        );
        return $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $queryParameters);
    }

    /**
     * Extract account  from  Account Json
     *
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */

    private function getAccountDetails($account,$key){
        $response = [];
        foreach ($account as $value) {
            if($value['Name'] == $key){
                $response['name'] = $value['Name'];
                $response['value'] = $value['Id'];
            }
        }
        return $response;
    }

    /**
     * Create quickbook invoice
     *
     * @param $request  slim request.
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */

    public function quickbookInvoiceCreate($orderDetails, $billing, $shipping, $quickBookLines, $orderId) {
        $pluginsInit = new PluginSettings();
        $quickStatus = $pluginsInit->where('catalog_code', 'quickbooks')
                ->where('status', 1);
        $pluginCountquick = $quickStatus->count();
        if($pluginCountquick > 0){
            if($orderDetails['order_details']['customer_id'] > 0 ) {
                $orderCustomer = $orderDetails['order_details'];
                $quickbookCustomerArr = [
                    'FullyQualifiedName' => $orderCustomer['customer_first_name'].$orderCustomer['customer_last_name'],
                    'PrimaryEmailAddr'=> [ "Address" => $orderCustomer['customer_email']],
                    "DisplayName" => $orderCustomer['customer_email'],
                    "FamilyName" => $orderCustomer['display_name'], 
                    "PrimaryPhone" => [ "FreeFormNumber" => $billing['phone'] ], 
                    "CompanyName" => $billing['company'], 
                    "BillAddr" => [
                        "CountrySubDivisionCode" => $orderDetails['currency'], 
                        "City" => $billing['city'], 
                        "PostalCode" => $billing['postcode'], 
                        "Line1" => $billing['address_1'], 
                        "Country" => $billing['country_code']
                    ]

                ];
            } else {
                $quickbookCustomerArr = [
                    'FullyQualifiedName' => $billing['first_name'],
                    'PrimaryEmailAddr'=> [ "Address" => $billing['email']],
                    "DisplayName" => $billing['email'],
                    "FamilyName" => $billing['first_name'], 
                    "PrimaryPhone" => [ "FreeFormNumber" => $billing['phone'] ], 
                    "CompanyName" => "Imprintnext", 
                    "BillAddr" => [
                        "CountrySubDivisionCode"=> $billing['country'], 
                        "City" => $billing['city'], 
                        "PostalCode" => $billing['postcode'], 
                        "Line1" => $billing['address_1'], 
                        "Country" => $billing['country_code']
                    ]
                ];
            }
            $customerId = $this->quickbookCustomerCreate($quickbookCustomerArr);     
            $orderDetails = $orderDetails['order_details'] ;
        
            $quickbookInvoiceArr = [
                "TxnDate" => $orderDetails['created_date'], 
                "domain" => "Imprintnext", 
                "PrintStatus" => "NeedToPrint", 
                "SalesTermRef" => [ "value" => "3"],
                "Line" =>  $quickBookLines, 
                "DueDate" => $orderDetails['created_date'], 
                "ApplyTaxAfterDiscount" => false, 
                "DocNumber"  =>  $orderId, 
                "sparse" => false,  
                "Deposit" => 0, 
                "Balance" => $orderDetails['total_amount'], 
                "CustomerRef" => [ "value" => $customerId ],
                "BillEmail" =>[ "Address" => $billing['email'] ], 
                "ShipAddr" => [
                "City" => $shipping['city'], 
                "Line1" => $shipping['address_1'], 
                "PostalCode" => $shipping['postcode'],
                "CountrySubDivisionCode" => $shipping['country_code']
                ], 
                "EmailStatus" => "NotSet", 
                "BillAddr" => [
                "City" => $billing['city'], 
                "Line1" => $billing['address_1'], 
                "PostalCode" => $billing['postcode'],
                "CountrySubDivisionCode" => $billing['country_code'],
                "Line2" => $billing['address_2'], 
                "Line1" => $billing['address_1'],
                ],
                "TotalAmt" => $orderDetails['total_amount']
            ];

            $parameters = json_encode($quickbookInvoiceArr,true);
            $this->generateAuthorizationHeader();
            $http_header = array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json'
            );
            $path = '/invoice?minorverison=63';
            $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
        }
    }


     /**
     * Creatre quickbook Item
     *
     * @param $itemArray  Item Params.
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */
    public function createItem($itemArray){
        $account = $this->getAccount();
        $account = $account['QueryResponse']['Account'];
        $IncomeAccountRef = $this->getAccountDetails($account,'Sales of Product Income');
        $AssetAccountRef = $this->getAccountDetails($account,'Inventory Asset');
        $ExpenseAccountRef = $this->getAccountDetails($account,'Cost of Goods Sold');
        $itemArray["IncomeAccountRef"] = $IncomeAccountRef ;
        $itemArray["AssetAccountRef"] = $AssetAccountRef;
        $itemArray["ExpenseAccountRef"] = $ExpenseAccountRef;
        $itemName = $itemArray['Name'];
        $this->generateAuthorizationHeader();
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $queryPath = '/query';
        $queryParameters = array(
                'query' => "select * from Item where name = '".$itemName."'",
                'minorversion' => 63
            );

        $result = $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $queryParameters);

        if(!empty($result['QueryResponse']['Item'])){
           $itemId = $result['QueryResponse']['Item'][0]['Id'];
        }
        else {
            $path = '/item?minorversion=63';
            $http_header = array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json'
            );
            $parameters = json_encode($itemArray,true);
            $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);            

           $itemId = $result['Item']['Id'];
        }
        if(isset($itemId)) {
            return ["name" => $itemName , "value" => $itemId ];
        }
    }

    /**
     * Create quickbook Estimate/Quotation
     *
     * @param $request  Slim request.
     * @param $response  Slim response.
     * @param $getAllFormData  Parameter for Estimation creation.
     * @param $quotationLastId  quotation ID
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */

    public function createEstimate($request, $response,$getAllFormData,$quotationLastId){
        $quotJson = json_clean_decode($getAllFormData['quote_data']);
        $productObj = new ProductsController();
        $itemArrayEstimate = [];
        $quoteTotal = $quotJson['quote_total'];
        $taxAmount = $quotJson['tax_amount'];
        $discountAmount = $quotJson['discount_amount'];
        ///////// Add New Item Shipping
        $itemArrayShipping = [
            "TrackQtyOnHand" => false, 
            "Name" => 'Shipping',
            "QtyOnHand" => 1000000,
            "InvStartDate" => date('Y-m-d'), 
            "Type" => "Service", 
        ];
        $itemReffShipping = $this->createItem($itemArrayShipping);
        $itemArrayEstimate[] = [
            "Description" => 'Shipping', 
            "DetailType" => "SalesItemLineDetail", 
            "SalesItemLineDetail" => [
                "TaxCodeRef" => [
                "value" => "NON"
                ],
                "Qty" => 1, 
                "UnitPrice" => $quotJson['shipping_amount'],
                "ItemRef" => $itemReffShipping
            ],
            "LineNum" => 1, 
            "Amount" => $quotJson['shipping_amount'], 
            "Id" => 1
        ];
        /////END
        foreach ($quotJson['items'] as $key => $value) {
            $productId = $value['product_id'];
            $variantId = $value['product_variant'][0]['variant_id'];
            $variantId = ($variantId > 0) ? $variantId : $productId ;
            $productArgs = [ 'product_id' => $productId , 'variant_id' => $variantId , 'details' => 1];
            $productShortDetails = $productObj->getStore()->getProductShortDetails($request, $response , $productArgs,1);
            if(!isset($productShortDetails['stock_quantity']) || $productShortDetails['stock_quantity'] == '' ){
                $productStock =  1000;
            }else{
                $productStock = $productShortDetails['stock_quantity'];
            }
            $itemName =  $productShortDetails['name'].'#'.$productId;
            $itemArray = [
                "TrackQtyOnHand" => true, 
                "Name" => $itemName,
                "QtyOnHand" => $productStock,                  
                "InvStartDate" => date('Y-m-d'), 
                "Type" => "Inventory", 
            ];
            $itemReff = $this->createItem($itemArray);
            $itemDesc = $itemName;
            $itemArrayEstimate[] = [
                "Description" => $itemDesc, 
                "DetailType" => "SalesItemLineDetail", 
                "SalesItemLineDetail" => [
                    "TaxCodeRef" => [
                        "value" => "NON"
                    ],
                    "Qty" => $value['quantity'], 
                    "UnitPrice" => $value['unit_total']/$value['quantity'],
                    "ItemRef" => $itemReff
                ],
                "LineNum" => $key+2, 
                "Amount" => $value['unit_total'], 
                "Id" => $key+2
            ];
        }            
        $customer['id']= $quotJson['customer_id'];
        $customersControllerInit = new CustomersController();
        $customerDetails = $customersControllerInit->allCustomers($request, $response,$customer, 1);
        $customerDetails = $customerDetails['data'];
        $billing = $customerDetails['billing_address'];
        $shipping = $customerDetails['shipping_address'][0];
        $estimateShippingArray = [
            "City" => $shipping['city'], 
            "Line1" => $shipping['address_1'], 
            "PostalCode" => $shipping['postcode'],
            "CountrySubDivisionCode" => $shipping['country']
        ];
        $estimateBillingArray = [
            "City" => $billing['city'], 
            "Line1" => $billing['address_1'], 
            "PostalCode" => $billing['postcode'],
            "CountrySubDivisionCode" => $billing['country']
        ];
        $customerName = $customerDetails['first_name'].$customerDetails['first_name'];
        $quickbookCustomerArr = [
            'FullyQualifiedName' => $customerName,
            'PrimaryEmailAddr'=> [ "Address" => $customerDetails['email']],
            "DisplayName" => $customerDetails['email'],
            "FamilyName" => $customerDetails['first_name'], 
            "PrimaryPhone" => [ "FreeFormNumber" => $billing['phone'] ], 
            "CompanyName" => 'Not Found', 
            "BillAddr" => [
                "CountrySubDivisionCode" => $billing['country'], 
                "City" => $billing['city'], 
                "PostalCode" => $billing['postcode'], 
                "Line1" => $billing['address_1'], 
                "Country" => $billing['country']
            ]
        ];
        $customerId = $this->quickbookCustomerCreate($quickbookCustomerArr);
        $PercentBased = $quotJson['discount_type'] == 'flat' ? false : true;
        $itemArrayEstimate[]=  [
            "DetailType" => "DiscountLineDetail",
            "Amount" => $discountAmount,
            "DiscountLineDetail" => [
            "DiscountAccountRef" => [
                "name" => "Discounts given", 
                  "value" => "86"
                ], 
                "PercentBased" => $PercentBased, 
                "DiscountPercent" => $discountAmount
            ]
        ];
        $estimateArray = [
            "ShipDate" => $quotJson['ship_by_date'],
            "ExpirationDate" => $quotJson['exp_delivery_date'],
            "TotalAmt"=> $quoteTotal,
            "DocNumber" => $quotationLastId,
             "TxnDate" => date("Y-m-d"),
            "BillEmail"=> [
                "Address"=> $customerDetails['email']
            ],
            "ShipAddr"=> $estimateShippingArray, 
            "PrintStatus"=> "NeedToPrint", 
            "EmailStatus"=> "NotSet", 
            "BillAddr"=> $estimateBillingArray, 
            "Line"=> $itemArrayEstimate , 
            "CustomerRef"=> [
                "name"=> $customerName, 
                "value"=> $customerId
            ], 
            "TxnTaxDetail"=> [
                "TotalTax"=> $taxAmount
            ],
            "ApplyTaxAfterDiscount"=> true
        ];
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        $path = '/estimate?minorversion=63';
        $parameters = json_encode($estimateArray,true);
        $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
        if(!empty($result['Estimate'])){
            $estimateId = $result['Estimate']['Id'];
            $quoteData['module_type'] = 'quotations';
            $quoteData['imp_id'] = $quotationLastId;
            $quoteData['quickbooks_id'] = $estimateId;
           // $quoteData['doc_number'] = $result['Estimate']['DocNumber'];
            $quotationObj = new ProductionQuickbooksRelation($quoteData);
            $quotationObj->save();
        }
    }

    /**
     * Create quickbook Estimate/Quotation
     *
     * @param $estimateId  Estimate Id of Quickbook.
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */
    public function getEstimationDetail($estimateId){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $queryPath = '/estimate/'.$estimateId;
        $parameters = array(
                'minorversion' => 63
            );
        $result = $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $parameters);        

        $result = $result['Estimate'];
        return $result;
    }

    /**
     * Create quickbook Estimate/Quotation
     *
     * @param $request  Slim request.
     * @param $response  Slim response.
     * @param $getAllFormData  Parameter for Estimation creation.
     * @param $quotationLastId  quotation ID
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */

    public function updateEstimate($request, $response,$getAllFormData,$quotationId){
        $quotJson = $getAllFormData;
        $productObj = new ProductsController();
        $itemArrayEstimate = [];
        $quoteTotal = $quotJson['quote_total'];
        $taxAmount = $quotJson['tax_amount'];
        $discountAmount = $quotJson['discount_amount'];
        ///////// Add New Item Shipping
        $itemArrayShipping = [
            "TrackQtyOnHand" => false, 
            "Name" => 'Shipping',
            "QtyOnHand" => 1000000,
            "InvStartDate" => date('Y-m-d'), 
            "Type" => "Service", 
        ];
        $itemReffShipping = $this->createItem($itemArrayShipping);
        $itemArrayEstimate[] = [
            "Description" => 'Shipping', 
            "DetailType" => "SalesItemLineDetail", 
            "SalesItemLineDetail" => [
                "TaxCodeRef" => [
                    "value" => "NON"
                ],
                "Qty" => 1, 
                "UnitPrice" => $quotJson['shipping_amount'],
                "ItemRef" => $itemReffShipping
            ],
            "LineNum" => 1, 
            "Amount" => $quotJson['shipping_amount'], 
            "Id" => 1
        ];
        /////END
       foreach ($quotJson['items'] as $key => $value) {
            $productId = $value['product_id'];
            $variantId = $value['product_variant'][0]['variant_id'];
            $variantId = ($variantId > 0) ? $variantId : $productId ;
            $productArgs = [ 'product_id' => $productId , 'variant_id' => $variantId , 'details' => 1];
            $productShortDetails = $productObj->getStore()->getProductShortDetails($request, $response , $productArgs);
            if(!isset($productShortDetails['stock_quantity']) || $productShortDetails['stock_quantity'] == '' ){
                $productStock =  1000;
            }else{
                $productStock = $productShortDetails['stock_quantity'];
            }
            $itemName =  $productShortDetails['name'].'#'.$productShortDetails['id'];
            $itemArray = [
                "TrackQtyOnHand" => true, 
                "Name" => $itemName,
                "QtyOnHand" => $productStock,
                "InvStartDate" => date('Y-m-d'), 
                "Type" => "Inventory", 
            ];
            $itemReff = $this->createItem($itemArray);
            $itemDesc = $itemName;
            $itemArrayEstimate[] = [
                "Description" => $itemDesc, 
                "DetailType" => "SalesItemLineDetail", 
                "SalesItemLineDetail" => [
                    "TaxCodeRef" => [
                        "value" => "NON"
                    ],
                    "Qty" => $value['quantity'], 
                    "UnitPrice" => $value['unit_total']/$value['quantity'],
                    "ItemRef" => $itemReff
                ],
                "LineNum" => $key+2, 
                "Amount" => $value['unit_total'], 
                "Id" => $key+2
            ];
        }
        $customer['id']= $quotJson['customer_id'];
        $customersControllerInit = new CustomersController();
        $customerDetails = $customersControllerInit->allCustomers($request, $response,$customer, 1);
        $customerDetails = $customerDetails['data'];
        $billing = $customerDetails['billing_address'];
        $shipping = $customerDetails['shipping_address'][0];
        $estimateShippingArray = [
            "City" => $shipping['city'], 
            "Line1" => $shipping['address_1'], 
            "PostalCode" => $shipping['postcode'],
            "CountrySubDivisionCode" => $shipping['country']
        ];
        $estimateBillingArray = [
            "City" => $billing['city'], 
            "Line1" => $billing['address_1'], 
            "PostalCode" => $billing['postcode'],
            "CountrySubDivisionCode" => $billing['country']
         ];
        $customerName = $customerDetails['first_name'].$customerDetails['first_name'];
        $quickbookCustomerArr = [
            'FullyQualifiedName' => $customerName,
            'PrimaryEmailAddr'=> [ "Address" => $customerDetails['email']],
            "DisplayName" => $customerDetails['email'],
            "FamilyName" => $customerDetails['first_name'], 
            "PrimaryPhone" => [ "FreeFormNumber" => $billing['phone'] ], 
            "CompanyName" => 'Not Found', 
            "BillAddr" => [
                "CountrySubDivisionCode" => $billing['country'], 
                "City" => $billing['city'], 
                "PostalCode" => $billing['postcode'], 
                "Line1" => $billing['address_1'], 
                "Country" => $billing['country']
            ]
        ];
        $quickBookObj = new QuickBookController();
        $customerId = $quickBookObj->quickbookCustomerCreate($quickbookCustomerArr);
        $PercentBased = $quotJson['discount_type'] == 'flat' ? false : true;
        $itemArrayEstimate[]=  [
            "DetailType" => "DiscountLineDetail",
            "Amount" => $discountAmount,
            "DiscountLineDetail" => [
                "DiscountAccountRef" => [
                  "name" => "Discounts given", 
                  "value" => "86"
                ], 
                "PercentBased" => $PercentBased, 
                "DiscountPercent" => $discountAmount
            ]
        ];
        $estimateArray = [
            "ShipDate" => $quotJson['ship_by_date'],
            "ExpirationDate" => $quotJson['exp_delivery_date'],
            "TxnDate" => date("Y-m-d"),
            "TotalAmt"=> $quoteTotal,
            "BillEmail"=> [
                "Address"=> $customerDetails['email']
            ],
            "ShipAddr"=> $estimateShippingArray, 
            "PrintStatus"=> "NeedToPrint", 
            "EmailStatus"=> "NotSet", 
            "BillAddr"=> $estimateBillingArray, 
            "Line"=> $itemArrayEstimate , 
            "CustomerRef"=> [
                "name"=> $customerName, 
                "value"=> $customerId
            ], 
            "TxnTaxDetail"=> [
                "TotalTax"=> $taxAmount
            ], 
            "ApplyTaxAfterDiscount"=> true
        ];
            
        $estimationObj = new ProductionQuickbooksRelation();
        $estimationData = $estimationObj->where('imp_id',$quotationId)->where('module_type','quotations');
        if($estimationData->count() > 0){
            $estimationData = $estimationData->first()->toArray();
            $estimateId = $estimationData['quickbooks_id'];
            //$estimateArray['DocNumber'] = $estimationData['doc_number'];
            $estimateArray['Id'] =   $estimateId; 
           
            $estimationDetail = $this->getEstimationDetail($estimateId);
            $estimateArray['SyncToken'] = $estimationDetail['SyncToken'];
            $estimateArray['TxnDate'] = date("Y-m-d");

            $http_header = array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json'
            );
            $path = '/estimate?minorversion=63';
            $parameters = json_encode($estimateArray,true);

            $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
            if(!empty($result['Estimate'])){
                //return 'Quickbook Estimation Updated';
            }
        }
    }

    /**
     * Create quickbook Estimate/Quotation
     *
     * @param $request  Slim request.
     * @param $response  Slim response.
     * @param $deleteIds  Estimate id of quickbook
     *
     * @author steve@imprintnext.com
     * @date   12 Apr 2022
     * @return JSON
     */

    public function deleteEstimate($request, $response,$deleteIds){
        $this->generateAuthorizationHeader();
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        $estimationObj = new ProductionQuickbooksRelation();
        foreach ($deleteIds as  $value) {
            $estimationData = $estimationObj->where('imp_id',$value)->where('module_type','quotations');
            if($estimationData->count() > 0){
                $estimationDataArray = $estimationData->first()->toArray();
                $estimateId = $estimationDataArray['quickbooks_id'];
                //$estimateArray['DocNumber'] = $estimationDataArray['doc_number'];
                $estimationData->delete();
                               
                $estimationDetail = $this->getEstimationDetail($estimateId);
                $syncToken = $estimationDetail['SyncToken'];
                $estimateArray['TxnDate'] = date("Y-m-d");

                $path = '/estimate?operation=delete&minorversion=63';
                $parameters = array(
                    "SyncToken" => $syncToken,
                    "Id" => $estimateId
                );
                $parameters = json_encode($parameters,true);
                $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);               
            }
        }      
        //return 'Removed From Quickbook';
    }

    /**
     * Check company Information
     *
     * @param $pluginsObj  Plugin setting object.
     *
     * @author steve@imprintnext.com
     * @date   05 May 2022
     * @return int
     */
    private function checkCompany(){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $path = '/query';
        $parameters = array(
                'query' => "select * from CompanyInfo",
                'minorversion' => 63
            );
        $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_GET, $parameters);
        return $result['QueryResponse']['CompanyInfo'][0]['SyncToken'];       
        
    }

    /**
     * Update company Information
     *
     * @param $postArray  Company Information
     *
     * @author steve@imprintnext.com
     * @date   06 May 2022
     * @return json
     */
    public function quickbookCompanyCreateUpdate($postArray){
        $SyncToken = $this->checkCompany();
        $companyArray = [
            "SyncToken" => $SyncToken, 
            "domain" => urlencode(API_URL), 
            "LegalAddr"=> [
                "City" => $postArray['city'], 
                "Line1" => urlencode($postArray['address']), 
                "PostalCode" => $postArray['zip_code'], 
                "CountrySubDivisionCode" => $postArray['country_id'], 
                "Id" => "1"
            ], 
            "SupportedLanguages" => "en", 
            "CompanyName" => $postArray['company_name'], 
            "Country" => $postArray['country'], 
            "CompanyAddr" => [
                "City" => $postArray['city'], 
                "Line1" => urlencode($postArray['address']), 
                "PostalCode" => urlencode($postArray['zip_code']), 
                "CountrySubDivisionCode" => $postArray['country_id'], 
                "Id" => "1"
            ],
            "sparse" => false, 
            "Id" => "1", 
            //"WebAddr" => urlencode(API_URL),
            "PrimaryPhone" => [
                "FreeFormNumber" => $postArray['phone_number']
            ], 
            "LegalName" => $postArray['company_name'], 
            "CompanyStartDate" => date("Y-m-d"), 
            "Email" => [
                "Address" => $postArray['sender_email']
            ]
        ];
        $path = '/companyinfo?minorversion=63';
        $parameters = json_encode($companyArray,true);
        $http_header = array(
           'Accept' => 'application/json',
           'Content-Type' => 'application/json'
        );
        $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
        if(!empty($result['CompanyInfo'])){
            return 1;
        }
        else {
            return 0;
        }
    }

    /**
     * Create Department
     *
     * @param $postArray  Company Information
     *
     * @author steve@imprintnext.com
     * @date   06 May 2022
     * @return json
     */
    public function quickbookCreateDepartment($postArray,$userTypeId){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $queryPath = '/query';
        $DeptParameters = array(
                'query' => "select * from Department where FullyQualifiedName = '".$postArray['role_name']."'",
                'minorversion' => 63
            );

        $result = $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $DeptParameters);
        if(empty($result['QueryResponse'])){
            $deptArray = [
                "Name" => $postArray['role_name'],
                "FullyQualifiedName"=> $postArray['role_name'],
            ];
            $path = '/department?minorversion=63';
            $parameters = json_encode($deptArray,true);
            $http_header = array(
               'Accept' => 'application/json',
               'Content-Type' => 'application/json'
            );
            $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
            if(!empty($result['Department'])){
                $departmentId = $result['Department']['Id'];
                $quoteData['module_type'] = 'user_type';
                $quoteData['imp_id'] = $userTypeId;
                $quoteData['quickbooks_id'] = $departmentId;
                $quotationObj = new ProductionQuickbooksRelation($quoteData);
                $quotationObj->save();
                return $departmentId;
            }
            else {
                return 0;
            }
        }       
        
    }

    private function getDepartmentDetail($departmentId){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        $queryPath = '/query';
        $parameters = array(
            'query' => "select * from Department where Id = '".$departmentId."'",'minorversion' => 63
        );
        return $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $parameters);
        
    }
    /**
     * Update Department
     *
     * @param $postArray  Company Information
     *
     * @author steve@imprintnext.com
     * @date   06 May 2022
     * @return json
     */
    public function quickbookUpdateDepartment($postArray,$userTypeId){
        $deptObj = new ProductionQuickbooksRelation();
        $departmentData = $deptObj->where('imp_id',$userTypeId)->where('module_type','user_type');
        if($departmentData->count() > 0){
            $departmentData = $departmentData->first()->toArray();
            $departmentId = $departmentData['quickbooks_id'];
            $deptDetail = $this->getDepartmentDetail($departmentId);
            $SyncToken = $deptDetail['QueryResponse']['Department'][0]['SyncToken'];
            $deptArray =  [
                "Name" => $postArray['role_name'],
                "FullyQualifiedName"=> $postArray['role_name'],
                "SyncToken" => $SyncToken, 
                "SubDepartment" => false, 
                "sparse" => false, 
                "Active" => true, 
                "Id" => $departmentId,
            ];
            $http_header = array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json'
            );
            $path = '/department?minorversion=63';
            $parameters = json_encode($deptArray,true);
            $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
        } 
    }

    /**
     * Delete Department/User Role
     *
     * @param $request  Slim request.
     * @param $response  Slim response.
     * @param $deleteIds  Estimate id of quickbook
     *
     * @author steve@imprintnext.com
     * @date   06 May 2022
     * @return int
     */

    public function quickbookDeleteDepartment($userTypeId){
        $departmentObj = new ProductionQuickbooksRelation();
        foreach ($userTypeId as $value) {
            $departmentData = $departmentObj->where('imp_id',$value)->where('module_type','user_type');  
            if($departmentData->count() > 0){
                $departmentArray = $departmentData->first()->toArray();
                $departmentData->delete();
                $departmentId = $departmentArray['quickbooks_id'];
                $deptDetail = $this->getDepartmentDetail($departmentId);
                $deptDetail = $deptDetail['QueryResponse']['Department'][0];
                $SyncToken = $deptDetail['SyncToken'];
                $deptArray =  [
                    "Name" => $deptDetail['Name'],
                    "FullyQualifiedName"=> $deptDetail['FullyQualifiedName'],
                    "SyncToken" => $SyncToken, 
                    "SubDepartment" => false, 
                    "sparse" => false, 
                    "Active" => false, 
                    "Id" => $departmentId,
                ];
                $http_header = array(
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                );
                $path = '/department?minorversion=63';
                $parameters = json_encode($deptArray,true);
                $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters); 

            }
        }      
        //return 'Removed From Quickbook';
    }

    /**
     * Create Employee
     *
     * @param $postArray  Company Information
     *
     * @author steve@imprintnext.com
     * @date   06 May 2022
     * @return int
     */
    public function quickbookCreateEmployee($postArray,$empId = 1){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        $queryPath = '/query';
        $queryParameters = array(
                'query' => "select * from Employee where GivenName = '".$postArray['email']."'",
                'minorversion' => 63
            );
        $result = $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $queryParameters);
        if(empty($result['QueryResponse']['Employee'])){
            $empArray = [
                "GivenName" => $postArray['email'],
                "EmployeeNumber" => $empId,
                "FamilyName" => "(".$postArray['name'].")",
                "PrimaryEmailAddr"=> [
                 "Address" => $postArray['email']
                ]
            ];
            $path = '/employee?minorversion=63';
            $parameters = json_encode($empArray,true);

            $result = $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
            if(!empty($result['Employee'])){
                $employeeId = $result['Employee']['Id'];
                $quoteData['module_type'] = 'user';
                $quoteData['imp_id'] = $empId;
                $quoteData['quickbooks_id'] = $employeeId;
                $quotationObj = new ProductionQuickbooksRelation($quoteData);
                $quotationObj->save();
                return $employeeId;
            }
            else {
                return 0;
            }
        }
        else{
            return $result['QueryResponse']['Employee']['Id'];
        }
        
    }

    private function getEmployeeDetail($emptId){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        $queryPath = '/query';
        $queryParameters = array(
            'query' => "select * from Employee where Id = '".$emptId."'",'minorversion' => 63
        );
        return $this->executeRequest($queryPath , $http_header, self::HTTP_METHOD_GET, $queryParameters);
        
    }
    /**
     * Update Employee
     *
     * @param $postArray  Company Information
     *
     * @author steve@imprintnext.com
     * @date   06 May 2022
     * @return int
     */
    public function quickbookUpdateEmployee($postArray,$empId = 1){
        $deptObj = new ProductionQuickbooksRelation();
        $empData = $deptObj->where('imp_id',$empId)->where('module_type','user');
        if($empData->count() > 0){
            $empData = $empData->first()->toArray();
            $QBEmpId = $empData['quickbooks_id'];
            $empDetail = $this->getEmployeeDetail($QBEmpId);
            $SyncToken = $empDetail['QueryResponse']['Employee'][0]['SyncToken'];
            $http_header = array(
               'Accept' => 'application/json',
               'Content-Type' => 'application/json'
            );
            $empArray = [
                "GivenName" => $postArray['email'],
                "SyncToken" => $SyncToken,
                "Id" => $QBEmpId,
                "EmployeeNumber" => $empId,
                "FamilyName" => "(".$postArray['name'].")",
                "PrimaryEmailAddr"=> [
                 "Address"=> $postArray['email']
                ]
            ];
            $parameters = json_encode($empArray,true);
            $path = '/employee?minorversion=63';
            return $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
            
        }
        
    }

    /**
     * Delete Employee Role
     *
     * @param $request  Slim request.
     * @param $response  Slim response.
     * @param $deleteIds  Estimate id of quickbook
     *
     * @author steve@imprintnext.com
     * @date   06 May 2022
     * @return int
     */

    public function quickbookDeleteEmployee($empId){ 
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        $employeeObj = new ProductionQuickbooksRelation();
        foreach ($empId as $value) {
            $employeeData = $employeeObj->where('imp_id',$value)->where('module_type','user');
            if($employeeData->count() > 0){
                $employeeArray = $employeeData->first()->toArray();
                $employeeData->delete();
                $QBId = $employeeArray['quickbooks_id'];
                $empDetail = $this->getEmployeeDetail($QBId);
                $empDetail = $empDetail['QueryResponse']['Employee'][0];
                $SyncToken = $empDetail['SyncToken'];
                $empArray = [
                    "GivenName" => $empDetail['GivenName'],
                    "DisplayName" => $empDetail['DisplayName'],
                    "SyncToken" => $SyncToken,
                    "Id" => $QBId,
                    "EmployeeNumber" => $empDetail['EmployeeNumber'],
                    "FamilyName" => $empDetail['FamilyName'],
                    "Active" => false,
                    "PrimaryEmailAddr"=> [
                    "Address"=> $empDetail['GivenName']
                    ]
                ];
                $parameters = json_encode($empArray,true);
                $path = '/employee?minorversion=63';
                return $this->executeRequest($path , $http_header, self::HTTP_METHOD_POST, $parameters);
                
            }
        }      
    }
    /**
     * Filter customer & post into quick-books
     *
     * @param $request  Slim request.
     * @param $response  Slim response.
     * 
     *
     * @author sonali@imprintnext.com
     * @date   05 may 2022
     * @return JSON
     */
    public function filterByCustomer($request, $response,$args){
        $jsonResponse = [
            'status' => 0,
            'message' => 'Customer not_found'
        ];
        $pluginsInit = new PluginSettings();
        $quickBookStatus = $pluginsInit->where('catalog_code', 'quickbooks')->where('status', 1);
        $quickBooksInstalled = $quickBookStatus->count();
        $today['updated_date'] = date("Y-m-d");
        $pluginsObj = new PluginSettings();
        $checkRecord = $pluginsObj->where(
            ['catalog_code' => 'quickbooks']
        );
        $checkRecord = $checkRecord->first()->toArray();
        $fromDate = $checkRecord['updated_date'];
        $params = array(
            'from_date' => $fromDate,
            'to_date' => $today['updated_date'],
            'order' => desc,
            'customer_no_order' => '',
            'orderby' => id,
            'per_page' => 10,
            'page' => 1,
            'name' => '',
            'store_id' => $request->getQueryParam('store_id') ? $request->getQueryParam('store_id') : 1,
        );
        $customerDetails = call_curl($params, 'customers', 'GET');
        $newCustomers = $customerDetails['data'];
        if(!empty($newCustomers) && $quickBooksInstalled){
            foreach($newCustomers as  $newValue){
                $customer['id'] = $newValue['id'];
                $customersControllerInit = new CustomersController();
                $customerDetails = $customersControllerInit->allCustomers($request, $response,$customer, 1);
                $customerDetails = $customerDetails['data'];
                $customerData = [
                    "FullyQualifiedName" => $customerDetails['first_name'].$customerDetails['last_name'],
                    "PrimaryEmailAddr" => [
                        "Address" => $customerDetails['email']
                    ],
                    "DisplayName" => $customerDetails['email'], 
                    "PrimaryPhone" => [
                        "FreeFormNumber" => $customerDetails['billing_address']['phone']
                    ],
                    "CompanyName" => "",
                    "BillAddr" => [
                        "CountrySubDivisionCode" => $customerDetails['billing_address']['country'], 
                        "City" => $customerDetails['billing_address']['city'],
                        "PostalCode" => $customerDetails['billing_address']['postcode'],
                        "Line1" => $customerDetails['billing_address']['address_1'],
                        "Country" => $customerDetails['billing_address']['country']
                    ],
                ];
                $createQuickBookCutomer = $this->quickbookCustomerCreate($customerData);
            }
            if($createQuickBookCutomer){
                $pluginsObj = new PluginSettings();
                $pluginsObj->where(['updated_date' => $fromDate])->update($today);
            }
            $jsonResponse = [
                'status' => 1,
                'message' => 'Customer imported'
                
            ];
        }
        return response(
            $response, [
                'data' => $jsonResponse
            ]
        );
    }
    /**
     * create Ghost cutomer into Quick-Books
     *
     * @param $customerDetails  for a customer.
     *
     * @author sonali@imprintnext.com
     * @date   05 may 2022
     * @return JSON
     */
    public function quickbookCustomer($customerDetails){
        $pluginsInit = new PluginSettings();
        $quickBookStatus = $pluginsInit->where('catalog_code', 'quickbooks')->where('status', 1);
        $quickBooksInstalled = $quickBookStatus->count();
        $jsonResponse = [
            'status' => 0,
            'message' => 'Customer Details not_found'
        ];
        if($quickBooksInstalled){
            $customerData = [
                "FullyQualifiedName" => $customerDetails['first_name'].$customerDetails['last_name'], 
                "PrimaryEmailAddr" => [
                    "Address" => $customerDetails['user_email']
                ],
                "DisplayName" => $customerDetails['user_email'], 
                "PrimaryPhone" => [
                    "FreeFormNumber" => $customerDetails['billing_phone']
                ],
                "CompanyName" => $customerDetails['company_name'],
                "BillAddr" => [
                    "CountrySubDivisionCode" => $customerDetails['billing_country_code'], 
                    "City" => $customerDetails['billing_city'],
                    "PostalCode" => $customerDetails['billing_postcode'],
                    "Line1" => $customerDetails['billing_address_1'],
                    "Country" => 'india',
                ],
            ];
            $this->quickbookCustomerCreate($customerData);
            $jsonResponse = [
                'status' => 0,
                'message' => 'a new cutomer created'
            ];
        }
        return $jsonResponse;
    }
    
    /**
     * create vendor in Quick-Books
     *
     * @param $allPostPutVars  for a vendor.
     * @param $storeVendorId imprintnextvendor Id.
     *
     * @author sonali@imprintnext.com
     * @date   06 may 2022
     * @return JSON
     */
    public function quickbookVendorCreate($allPostPutVars,$storeVendorId){
        $emailAddress = $allPostPutVars['DisplayName'];
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $tokenEndPointMailIdCheck = '/query';
        $vendorParameters = array(
            'query' => "select * from vendor Where DisplayName = '".$emailAddress."'",
            'minorversion' => 63
        );

        $result = $this->executeRequest($tokenEndPointMailIdCheck , $http_header, self::HTTP_METHOD_GET, $vendorParameters);        
        if(!empty($result['QueryResponse']['Vendor'])){
           $vendorId = $result['QueryResponse']['Vendor'][0]['Id'];
        }
        else {
            $tokenEndPointUrl = '/vendor?minorversion=63';
            $parameters = json_encode($allPostPutVars,true);
            $this->generateAuthorizationHeader();
            $http_header = array(
                'Accept' => 'application/json',
                'Content-Type' => 'application/json'
            );
            $result = $this->executeRequest($tokenEndPointUrl, $http_header, self::HTTP_METHOD_POST, $parameters);
            $vendorId = $result['Vendor']['Id'];
        }
        if($vendorId) {
            $saveData = [
                'module_type' => 'vendor',
                'imp_id' => $storeVendorId,
                'quickbooks_id' => $vendorId,
            ];
            $vendorInit = new ProductionQuickbooksRelation($saveData);
            $vendorInit->save();
            return ["name" => $emailAddress , "value" => $vendorId ];
        }
    }
    /**
     * prepare json for create vendor in Quick-books
     *
     * @param $vendorDetails of a vendor.
     * @param $storeVendorId  (imprintnext).
     
     * @author sonali@imprintnext.com
     * @date   06 may 2022
     * @return JSON
     */
    public function quickbookVendor($vendorDetails,$storeVendorId){
        $pluginsInit = new PluginSettings();
        $quickBookStatus = $pluginsInit->where('catalog_code', 'quickbooks')->where('status', 1);
        $quickBooksInstalled = $quickBookStatus->count();
        if($quickBooksInstalled){
            $vendorData = [
                "PrimaryEmailAddr" => [
                    "Address" => $vendorDetails['email']
                ],
                "PrimaryPhone" => [
                    "FreeFormNumber" => $vendorDetails['phone']
                ], 
                "DisplayName" => $vendorDetails['email'],
                "CompanyName" => $vendorDetails['company_name'],
                "BillAddr" => [
                    "City" => $vendorDetails['city'], 
                    "Country" => $vendorDetails['country_code'], 
                    "Line3" => '', 
                    "Line2" => '', 
                    "Line1" => $vendorDetails['billing_address'], 
                    "PostalCode" =>$vendorDetails['zip_code'], 
                    "CountrySubDivisionCode" => $vendorDetails['country_code']
                ]
            ];
            $createQuickbookVendor = $this->quickbookVendorCreate($vendorData,$storeVendorId);
        }
        return $createQuickbookVendor;
    }

    /**
     * Read a vendor Details
     *@param $searchKey vendor name of Quickbook.
     *
     * @author sonali@imprintnext.com
     * @date   06 may 2022
     * @return JSON
     */
    public function readVendorDetails($searchKey){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded'
        );
        $tokenEndPointUrl = '/query';

        $parameters = array(
                'query' => "select * from vendor Where DisplayName = '".$searchKey."'",               
                'minorversion' => 63
            );        
        $result = $this->executeRequest($tokenEndPointUrl , $http_header, self::HTTP_METHOD_GET, $parameters);
        $result = $result['QueryResponse']['Vendor'][0];
        return $result;
    }
    /**
     * Update a vendor 
     *@param $vendorInfo vendordetails of Quickbook
     *@param $impId Imprintnext vendor id.
     * @author sonali@imprintnext.com
     * @date   06 may 2022
     * @return JSON
     */

    public function vendorUpdate($vendorInfo,$impId){
        $pluginsInit = new PluginSettings();
        $quickBookStatus = $pluginsInit->where('catalog_code', 'quickbooks')->where('status', 1);
        $quickBooksInstalled = $quickBookStatus->count();
        $jsonResponse = [
            'status' => 0,
            'message' => 'Customer Details not_found'
        ];
        $vendorInit = new ProductionQuickbooksRelation();
        $vendorInitSatus = $vendorInit->where('module_type','vendor')->where('imp_id',$impId);
        $vendorInitSatus = $vendorInitSatus->get()->toArray();
        // $vendorId = $vendorInitSatus[0]['quickbooks_id'];
        $getSyncDetails = $this->readVendorDetails($vendorInfo['email']);
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        if($quickBooksInstalled){
            $vendorUpdateData = [
                "PrimaryEmailAddr" => [
                    "Address" => $vendorInfo['email']
                ], 
                "DisplayName" => $vendorInfo['email'],
                "SyncToken" => $getSyncDetails['SyncToken'],
                "BillAddr" => [
                    "City" => $vendorInfo['city'], 
                    "Line1" => $vendorInfo['billing_address'], 
                    "PostalCode" => $vendorInfo['zip_code'], 
                    "CountrySubDivisionCode" => $vendorInfo['country_code'],
                    'Id' =>  $getSyncDetails['BillAddr']['Id']
                ],
                "PrimaryPhone" => [
                    "FreeFormNumber" => $vendorInfo['phone']
                ],
                "CompanyName" => $vendorInfo['company_name'], 
                 "Id" => $getSyncDetails['Id'],
            ];
            $tokenEndPointUrl = '/vendor?minorversion=63';
            $parameters = json_encode($vendorUpdateData,true);
            $this->executeRequest($tokenEndPointUrl , $http_header, self::HTTP_METHOD_POST, $parameters);
            $jsonResponse = [
                'status' => 1,
                'message' => 'Vendor updated'
            ];
        }
        return $jsonResponse;
    }
    /**
     * create purchase order Response body 
     *@param $poDetails purchae order details
     
     * @author sonali@imprintnext.com
     * @date   11 may 2022
     * @return JSON
     */
    public function createPurchaseOrder($request,$args,$poDetails){
        $pluginsInit = new PluginSettings();
        $quickBookStatus = $pluginsInit->where('catalog_code', 'quickbooks')->where('status', 1);
        $quickBooksInstalled = $quickBookStatus->count();
        if($quickBooksInstalled){
            foreach($poDetails as $poValue){
                $storeVendorId = $poValue['vendor_id'];
                $purchaseOrderControllerInit = new PurchaseOrderController();
                $vendorDetails = $purchaseOrderControllerInit->getVendorDetailsById($storeVendorId);
                $vendorDetails = $this->quickbookVendor($vendorDetails,$storeVendorId);
                $account = $this->getAccount();
                $account = $account['QueryResponse']['Account'];
                $APAccountRef = $this->getAccountDetails($account,'Accounts Payable (A/P)');
                $purchaseOrder['APAccountRef'] = $APAccountRef;
                $itemRef = [];
                $lineItem = [];
                foreach($poValue['po_items'] as $itemValue){
                    $args['id'] = $itemValue['order_id'];
                    $orderInit = new OrdersController();
                    $orderArray = $orderInit->getOrders($request, $response, $args);
                    
                    if($orderArray['order_details']['customer_id'] > 0 ) {
                        $orderCustomer = $orderArray['order_details'];
                        $billing = $orderArray['order_details']['billing'];
                        $quickbookCustomerArr = [
                            'FullyQualifiedName' => $orderCustomer['customer_first_name'].$orderCustomer['customer_last_name'],
                            'PrimaryEmailAddr'=> [ "Address" => $orderCustomer['customer_email']],
                            "DisplayName" => $orderCustomer['customer_email'],
                            "FamilyName" => $orderCustomer['display_name'],
                            "PrimaryPhone" => [ "FreeFormNumber" => $billing['phone'] ],
                            "CompanyName" => $billing['company'],
                            "BillAddr" => [
                                "CountrySubDivisionCode" => $orderCustomer['currency'],
                                "City" => $billing['city'],
                                "PostalCode" => $billing['postcode'],
                                "Line1" => $billing['address_1'],
                                "Country" => $billing['country_code']
                            ]
                        ];
                    }else {
                        $quickbookCustomerArr = [
                            'FullyQualifiedName' => $billing['first_name'],
                            'PrimaryEmailAddr'=> [ "Address" => $billing['email']],
                            "DisplayName" => $billing['email'],
                            "FamilyName" => $billing['first_name'],
                            "PrimaryPhone" => [ "FreeFormNumber" => $billing['phone'] ],
                            "CompanyName" => "Imprintnext",
                            "BillAddr" => [
                                "CountrySubDivisionCode"=> $billing['country'],
                                "City" => $billing['city'],
                                "PostalCode" => $billing['postcode'],
                                "Line1" => $billing['address_1'],
                                "Country" => $billing['country_code']
                            ]
                        ];
                    }
                    $customerId = $this->quickbookCustomerCreate($quickbookCustomerArr);
                    $orderLineItem = $orderArray['order_details']['orders'];
                    foreach($orderLineItem as $lineValue){
                        if($lineValue['id'] == $itemValue['item_id']){
                            $itemData = [
                                "TrackQtyOnHand" => true,
                                "Name" => urlencode($lineValue['name']), 
                                "QtyOnHand" => $lineValue['quantity'], 
                                "InvStartDate" => date('Y-m-d'), 
                                "Type" => "Inventory", 
                            
                            ];
                            $itemRef = $this->createItem($itemData);
                            $line = [
                                "DetailType" => "ItemBasedExpenseLineDetail", 
                                "Amount" => $lineValue['price'], 
                                "ItemBasedExpenseLineDetail"=>[
                                    "ItemRef"=> $itemRef,
                                    "CustomerRef"=> [
                                        "name" => $orderCustomer['customer_email'], 
                                        "value" => $customerId
                                    ], 
                                    "Qty"=> $lineValue['quantity'], 
                                    "TaxCodeRef"=> [
                                    "value"=> "NON"
                                    ], 
                                    "BillableStatus"=> "NotBillable", 
                                    "UnitPrice"=> $lineValue['total'],
                                ]
                            ];
                        }
                    }
                    $lineItem[] = $line;
                }
                
                $purchaseData = [
                    "Line" => $lineItem,
                    "TxnDate" => date("Y-m-d"),
                    "APAccountRef"=> $APAccountRef, 
                    "VendorRef" => $vendorDetails,
                ];            
                $order[] = $purchaseData;
            }
            foreach($order as  $orderValue){
                $result[] =  $this->quickbookCreatePurchaseOrder($orderValue);
            }
            return $result;
        }   
    }
    /**
     * create purchase order in quick-books
     *@param $allPostPutVars
     
     * @author sonali@imprintnext.com
     * @date   13 may 2022
     * @return JSON
     */

    public function quickbookCreatePurchaseOrder($allPostPutVars){
        $http_header = array(
            'Accept' => 'application/json',
            'Content-Type' => 'application/json'
        );
        $tokenEndPointMailIdCheck = '/purchaseorder?minorversion=63';
        $purchaseParameters = json_encode($allPostPutVars,true);
        $result = $this->executeRequest($tokenEndPointMailIdCheck, $http_header, self::HTTP_METHOD_POST,  $purchaseParameters);
        return $result['QueryResponse']['PurchaseOrder'][0]['Id'];
        
    }

}