<?php 
class Service_GetDHLInfoProcess extends Common_Service{
    const  API_DOMAIN    = 'https://api.dhlecommerce.dhl.com';
    const  API_USER_ID   = 'LTEyNDY2OTMxMzg=';
    const  API_PASSWORD  = 'MjAzMDI5MTU'; 
    const  RETURN_FORMAT = 'json';
    private static $_errorMessage = '';
    private static $_accessToken = '';
    private static $_pickupAccountId = '520678';//DHL PICKUP Account ID
    private static $_soldToAccountId = '520678';//DHL SOLDTO Account ID
    
    public function __construct(){
    }
    
    //获取token信息
    public static  function getTokenInfo(){
        $accessTokenUrl = self::API_DOMAIN.'/rest/v1/OAuth/AccessToken?clientId='.self::API_USER_ID.'&password='.self::API_PASSWORD.'&returnFormat='.self::RETURN_FORMAT;
        $response =  json_decode(self::http($accessTokenUrl,''),true);//将json数据解析为多维数组
        return $response;
    }
    //查询轨迹
    public static function getTrackingService(){
        
    }
    //查询标签
    public static function getLabelDataService($orderInfos,$debug){
        date_default_timezone_set('PRC');//设置时区
        $result = array( 
                'status' => 1,
                'message' => 'successfully'
        );
        $accessLabelDataUrl = self::API_DOMAIN.'/rest/v2/Label';
        //读取token数据
        $tokenRecordFile = APPLICATION_PATH . '/../data/log/tokenRecordFile.lock';
        if(file_exists($tokenRecordFile)){
            $str = file_get_contents($tokenRecordFile);//将整个文件内容读入到一个字符串中
            $content = json_decode($str,true);
            $timeDifference = strtotime(date('Y-m-d H:i:s')) - (strtotime($content['accessTime']) + $content['expiresTime']);
            if($timeDifference >=0){//表示token过期,10秒缓冲时间
                @unlink($tokenRecordFile);
                $tokenInfo = self::getTokenInfo();
                if($tokenInfo['accessTokenResponse']['responseStatus']['code'] != 100000){
                    $result = array(
                        'status' => 0,
                        'message' => '访问接口获取token失败！'
                    );
                    return $result;
                }
                $tokenRecord = array(
                    'token'=>$tokenInfo['accessTokenResponse']['token'],
                    'expiresTime'=>$tokenInfo['accessTokenResponse']['expires_in_seconds'],
                    'accessTime'=>date('Y-m-d H:i:s'),
                );
                self::$_accessToken = $tokenInfo['accessTokenResponse']['token'];
                $jsonString = json_encode($tokenRecord);
                $link = fopen($tokenRecordFile, 'wb');
                fwrite($link, $jsonString);
                fclose($link);
            }else{ 
                self::$_accessToken = $content['token'];
            }
        }else{
            $tokenInfo = self::getTokenInfo();
            if($tokenInfo['accessTokenResponse']['responseStatus']['code'] != 100000){
                $result = array(
                    'status' => 0,
                    'message' => '访问接口获取token失败！'
                );
                return $result;
            }
            $tokenRecord = array(
                'token'=>$tokenInfo['accessTokenResponse']['token'],
                'expiresTime'=>$tokenInfo['accessTokenResponse']['expires_in_seconds'],
                'accessTime'=>date('Y-m-d H:i:s'),
            );
            self::$_accessToken = $tokenInfo['accessTokenResponse']['token'];
            $jsonString = json_encode($tokenRecord);
            $link = fopen($tokenRecordFile, 'wb');
            fwrite($link, $jsonString);
            fclose($link);
        }
        $msssageDateTime = $pickupDateTime = date('c'); //生成ISO 8601 格式的日期
        //通过系统订单号查询数据
        $shipmentItems = array();
        //$orderInfos[] = Service_Orders::getByField('DOEC0011306280001','order_code');
        foreach($orderInfos as $key=>$orderinfo){
            //查询产品订单 行
            $orderProducts = Service_OrderProduct::getByCondition(array('order_code'=>$orderinfo['order_code']),'*');
            foreach($orderProducts as $k=>$v){
                $product = Service_Product::getByField($v['product_id'],"product_id","*");
                $orderProducts[$k]['product_sku']    = $product['product_sku'];
                $orderProducts[$k]['product_title']  = $product['product_title'];
                $orderProducts[$k]['product_weight'] = $product['product_weight'];
                $orderProducts[$k]['product_net_weight'] = $product['product_net_weight'];
                $orderProducts[$k]['with_battery'] = $product['with_battery'];
                $orderProducts[$k]['hs_code']        = $product['hs_code'];
            }
            $orderAddressBook = Service_OrderAddressBook::getByField($orderinfo['order_code'],'order_code');
            if(!empty($orderAddressBook)){
                $country = Service_Country::getByField($orderAddressBook['oab_country_id']);
                $countryCode = $country['country_code']; //国家名称国际简称
            }
           
            if($orderinfo['sm_code'] == 'DGM-US'){
                $filePath = APPLICATION_PATH . '/../data/file/USA-state-validity.xlsx';
                $fileData = Common_Upload::readEXCEL($filePath);
                $state    = '';
                foreach ($fileData as $k => $v) {
                    if ($k == 0) {
                        continue;
                    }
                    $str = strpos(strtolower($orderAddressBook['oab_state']), strtolower($v[1]));
                    if (is_numeric($str)) {
                        $state = $v[0]; //对应的州二字码
                        break;
                    }
                }
            }else{
                $state = $orderAddressBook['oab_state'];
            }
            $shipmentItems[$key]["consigneeAddress"] = array(
                "companyName"=>$orderAddressBook['oab_company']?$orderAddressBook['oab_company']:null,
                "name"=>$orderAddressBook['oab_firstname']?$orderAddressBook['oab_firstname']:null,
                "address1"=>$orderAddressBook['oab_street_address1']?$orderAddressBook['oab_street_address1']:null,
                "address2"=>$orderAddressBook['oab_street_address2']?$orderAddressBook['oab_street_address2']:null,
                "address3"=>$orderAddressBook['oab_street_address3']?$orderAddressBook['oab_street_address3']:null,
                "city"=>$orderAddressBook['oab_city']?$orderAddressBook['oab_city']:null,
                "state"=>$state?$state:null,
                "district"=>null,
                    
                "country"=>$countryCode,
                "postCode"=>$orderAddressBook['oab_postcode']?$orderAddressBook['oab_postcode']:null,
                "phone"=>$orderAddressBook['oab_cell_phone']?$orderAddressBook['oab_cell_phone']:null,
                "email"=>$orderAddressBook['oab_email']?$orderAddressBook['oab_email']:null
            );
            if($orderinfo['sm_code'] == 'DGM-US'){
                $shipmentItems[$key]["returnAddress"] = array(
                    "companyName"=> "Globex eServices Limited",
                    "name"=> "Shelly",
                    "address1"=> "Covina",
                    "address2"=> "null",
                    "address3"=> "null",
                    "city"=> "Covina",
                    "state"=> "CA",
                    "district"=> "null",
                    "country"=> "US",
                    "postCode"=> "91740",
                    "phone"=> "00012345",
                    "email"=> "SERVICE@GLOBEX.CN"
                );
            }else{
                $shipmentItems[$key]["returnAddress"] = array(
                    "companyName"=> "Globex eServices Limited",
                    "name"=> "Carina Peng",
                    "address1"=> "First Floor , no. 5 Building,",
                    "address2"=> "Qianhai bay bonded port Area, no.53 ,Linhai road,",
                    "address3"=> "Nanshan district ,",
                    "city"=> "Shenzhen",
                    "state"=> "Guangdong",
                    "district"=> "null",
                    "country"=> "CN",
                    "postCode"=> "518000",
                    "phone"=> "0755-26679863",
                    "email"=> "Carinapeng@globex.cn"
                );
            }
            $shipmentItems[$key]["shipmentID"]='HKOW'.$orderinfo['order_code'];
            $shipmentItems[$key]["deliveryConfirmationNo"]=null;
            $shipmentItems[$key]["packageDesc"]=$orderProducts['0']['product_title_en'];//指包裹描述，随意取订单内某个产品的英文品名即可
            $totalWeight = '';
            $totalValue  = '';
            $withBattery = 0;
            foreach($orderProducts as $orderProduct){
            	$totalWeight += $orderProduct['op_quantity'] * $orderProduct['product_weight'];
            	$totalValue  += $orderProduct['op_quantity'] * $orderProduct['op_purpose_declared_value'];
            	if($orderProduct['with_battery'] == 1){
            	    $withBattery = 1;
            	}
            }
            
            $shipmentItems[$key]["totalWeight"]=round($totalWeight*1000,3);//指包裹重量，将订单内所有产品重量求和即可
            $shipmentItems[$key]["totalWeightUOM"]='G';//重量单位
            $shipmentItems[$key]["dimensionUOM"]=null;//尺寸单位
            $shipmentItems[$key]["height"]=null;
            $shipmentItems[$key]["length"]=null;
            $shipmentItems[$key]["width"]=null;
            $shipmentItems[$key]["customerReference1"]=null;//not in use
            $shipmentItems[$key]["customerReference2"]=null;//not in use
            //productCode是指产品代码，如果是CJ-DGMG，就是PPS，如果是CJ-DGMP，就是PKD
            $incoterm = 'DDU';//默认值
            if($orderinfo['sm_code'] == 'CJ-DGMG'){
                $productCode = 'PPS';
            }
            if($orderinfo['sm_code'] == 'CJ-DGMP'){
                $productCode = 'PKD';
            }
            if($orderinfo['sm_code'] == 'DGM-US'){
                $productCode = 'PLE';
                $incoterm = 'DDP';
            }
            $shipmentItems[$key]["productCode"]=$productCode;
            $shipmentItems[$key]["incoterm"]=$incoterm;//默认为DDU
            $shipmentItems[$key]["contentIndicator"]=$withBattery ? '04' : '00'; //产品带电池为04，不带电池为00
            $shipmentItems[$key]["codValue"]=0;
            $shipmentItems[$key]["insuranceValue"]=0;
            $shipmentItems[$key]["freightCharge"]=0;
            $shipmentItems[$key]["totalValue"]=$totalValue;//指订单目的地海关申报总价
            $shipmentItems[$key]["currency"]='USD';//申报货币代码 
            
            foreach($orderProducts as $orderProduct){
            	$shipmentItems[$key]['shipmentContents'][] = array(
            		"skuNumber"=>$orderProduct["product_sku"]?$orderProduct["product_sku"]:null,
                    "description"=>$orderProduct["product_title_en"]?$orderProduct["product_title_en"]:null,
                    "descriptionImport"=>null,
                    "descriptionExport"=>$orderProduct["product_title"]?$orderProduct["product_title"]:null,
                    "itemValue"=>(float)$orderProduct["op_purpose_declared_value"],//强制转换为浮点型数据
                    "itemQuantity"=>(int)$orderProduct["op_quantity"],//强制转换为整型数据
                    "grossWeight"=>null,
                    "weightUOM"=>'G',
                    "netWeight"=>null,
                    "contentIndicator"=>($orderProduct['with_battery'] == 1) ? '04' : '00',//产品带电池为04，不带电池为00
                    "countryOfOrigin"=>$orderProduct["countryOfOrigin"]?$orderProduct["countryOfOrigin"]:'CN',
                    "hsCode"=>$orderProduct["hs_code"]?$orderProduct["hs_code"]:null,
            	);
            }
        }
        //echo count($shipmentItems);
        if(count($shipmentItems) >=100){
            $shipmentItems = array_chunk($shipmentItems, 100); //每次发送100个订单查询
        }else{
            $shipmentItems = array($shipmentItems);
        }
        
        foreach($shipmentItems as $key=>$shipmentItem){
            $requestData = array(
                'hdr'=>array(
                    'messageType'    => 'LABEL',
                    'messageDateTime'=> $msssageDateTime,
                    'accessToken'    => self::$_accessToken,
                    'messageVersion' => '1.4',
                    'messageLanguage'=> 'en'
                ),
                'bd'=>array(
                    "customerAccountId"=> null,
                    "pickupAccountId"  => self::$_pickupAccountId,
                    "soldToAccountId"  => self::$_soldToAccountId,
                    "pickupDateTime"   => $pickupDateTime ? $pickupDateTime : '',
                    "pickupAddress"    =>array(
                        "companyName"=> "Globex eServices Limited",
                        "name"=> "Carina Peng",
                        "address1"=> "First Floor , no. 5 Building,",
                        "address2"=> "Qianhai bay bonded port Area, no.53 ,Linhai road,",
                        "address3"=> "Nanshan district ,",
                        "city"=> "Shenzhen",
                        "state"=> "Guangdong",
                        "district"=> "null",
                        "country"=> "CN",
                        "postCode"=> "518000",
                        "phone"=> "0755-26679863",
                        "email"=> "Carinapeng@globex.cn"
                    ),
                    "shipperAddress"    =>array(
                        "companyName"=> "Globex eServices Limited",
                        "name"=> "Carina Peng",
                        "address1"=> "First Floor , no. 5 Building,",
                        "address2"=> "Qianhai bay bonded port Area, no.53 ,Linhai road,",
                        "address3"=> "Nanshan district ,",
                        "city"=> "Shenzhen",
                        "state"=> "Guangdong",
                        "district"=> "null",
                        "country"=> "CN",
                        "postCode"=> "518000",
                        "phone"=> "0755-26679863",
                        "email"=> "Carinapeng@globex.cn"
                    ),
                    "shipmentItems"   => $shipmentItem,
                    "label"=>array(
                        "pageSize"=> "400x600",
                        "format"=> "PDF",
                        "layout"=> "1x1"
                    )
                )
            );
            $data['data']['labelRequest'] = $requestData;
            $data['option']= array(
                'type'=>'POST',
                /* 'header'=>array(
                    'Content-Type: application/json',
                    "Content-Length: '". strlen(json_encode($data['data']))
                ), */
            );
            /* echo  '<pre>';
            var_dump($data['data']);
            echo '</pre>';
            exit(); */
            $response = json_decode(self::http($accessLabelDataUrl, $data),true);//将json数据解析为多维数组
            if($debug){
                $logPath = APPLICATION_PATH . '/../data/logInfo';
                $fileReq = APPLICATION_PATH . '/../data/logInfo/request.txt';
                $fileRes = APPLICATION_PATH . '/../data/logInfo/response.txt';
                if(!is_readable($logPath)){
                    is_file($logPath) or mkdir($logPath,0755);
                }
                $fpReq=fopen($fileReq, "w+");
                file_put_contents($fileReq,json_encode($data['data']));
                fclose($fpReq);
                $fpRes=fopen($fileRes, "w+");
                file_put_contents($fileRes, json_encode($response));
                fclose($fpRes);
            }
            if(!empty(self::$_errorMessage)){
                $result['status']  = '0';
                $result['message'] = self::$_errorMessage;
                break;
            }
            //var_dump($response);
            if(!in_array($response['labelResponse']['bd']['responseStatus']['code'], array('200','204'))){
                $result['status']  = '0';
                $result['message'] = '接口返回数据失败！=>'.$response['labelResponse']['bd']['responseStatus']['message'];
                //写错误日志
                foreach($response['labelResponse']['bd']['labels'] as $label){
                    $sysOrderCode = substr($label['shipmentID'], '4');
                    $messageDetailString = '';
                    foreach($label['responseStatus']['messageDetails'] as $messageKey=>$messageDetail){
                        if($messageKey != 0){
                            $sqlitStr = ';';
                        }
                        $messageDetailString .= $sqlitStr.$messageDetail['messageDetail'];
                    }
                    $sysOrderInfo = Service_Orders::getByField($sysOrderCode,'order_code','sm_code');//主要查询运输方式
                    $errorLog = array('order_code'=>$sysOrderCode,'sm_code'=>$sysOrderInfo['sm_code'],'content'=>$messageDetailString);
                    $errorLogId = Service_TrackingErrorLog::add($errorLog);
                    if(empty($errorLogId)){
                        $result['status'] = '0';
                        $result['message'] = '回写接口返回错误信息数据失败！';
                        break;
                    }
                }
                break;
            }
            foreach($response['labelResponse']['bd']['labels'] as $label){
                $sysOrderCode = substr($label['shipmentID'], '4');
                if($label['responseStatus']['code'] == '200' || $label['responseStatus']['code'] == '203'){
                    if(!empty($label['content'])){
                        $row = array(
                            'order_code' =>$sysOrderCode,
                            'ol_content' =>$label['content'],
                            'ol_time'    =>date("Y-m-d H:i:s")
                        );
                        //保存返回标签数据
                        $ordersLabelId = Service_OrdersLabel::add($row);
                        if(empty($ordersLabelId)){
                            $result['status']  = '0';
                            $result['message'] = '回写返回标签数据失败！';
                            break;
                        }
                        //保存返回跟踪号
                        //对接时，CJ-DGMP是没有返回跟踪号的，在取回标签时，请自动往orders表的跟踪号赋上订单号
                        $sysOrderInfo = array();
                        if(empty($label['deliveryConfirmationNo'])){
                            $sysOrderInfo = Service_Orders::getByField($sysOrderCode,'order_code','sm_code');//主要查询运输方式
                        }
                        if(strtoupper($sysOrderInfo['sm_code']) == 'CJ-DGMP'){
                            $label['deliveryConfirmationNo'] = $sysOrderCode;
                        }
                        if(strtoupper($sysOrderInfo['sm_code']) == 'DGM-US'){
                            $label['deliveryConfirmationNo'] = $label['shipmentID'];
                        }
                        $ordersId = Service_Orders::updateIn(array('ref_tracking_number'=>$label['deliveryConfirmationNo'],'update_time'=>date("Y-m-d H:i:s")), array($sysOrderCode));
                        unset($sysOrderCode);
                        if(empty($ordersId)){
                            $result['status']  = '0';
                            $result['message'] = '回写返回跟踪号数据失败！';
                            break;
                        }
                    }
                }else{
                    $messageDetailString = '';
                    foreach($label['responseStatus']['messageDetails'] as $messageKey=>$messageDetail){
                        if($messageKey != 0){
                            $sqlitStr = ';';
                        }
                        $messageDetailString .= $sqlitStr.$messageDetail['messageDetail'];
                    }
                    $sysOrderInfo = Service_Orders::getByField($sysOrderCode,'order_code','sm_code');//主要查询运输方式
                    $errorLog = array('order_code'=>$sysOrderCode,'sm_code'=>$sysOrderInfo['sm_code'],'content'=>$messageDetailString);
                    $errorLogId = Service_TrackingErrorLog::add($errorLog);
                    if(empty($errorLogId)){
                        $result['status'] = '0';
                        $result['message'] = '回写接口返回错误信息数据失败！';
                        break;
                    }
                }
            }
        }
        //测试返回请求数据
        if($debug){
            $result['labelRequest'] = $data['data'];
            $result['labelResponse'] = $response['labelResponse'];
        }
        
        return $result;
    }
    
    
    /**
     * 利用php_curl创建HTTP请求
     *
     * @param string  $url     请求的URL
     * @param array   $data    发送的数据
     * @param string           返回请求结果
     * @return mixed           失败返回FALSE，否则返回请求执行结果
     */
    private static function http($url, $data){
        // 不存在扩展，退出请求
        if (!extension_loaded('curl')) {
            self::$_errorMessage = 'Service_Sto::http()没有加载curl扩展';
            return false;
        }
    
        $scheme = parse_url($url, PHP_URL_SCHEME);
        $curl   = curl_init($url);
    
        if (false === $curl) {
            self::$_errorMessage = 'Service_GetDHLInfoProcess::http()初始化curl发生异常';
            return false;
        }
    
        curl_setopt($curl, CURLOPT_TIMEOUT, 0);// 超时时间（秒）
        curl_setopt($curl, CURLOPT_HEADER, false);// 禁止头文件输出
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);// 以文件流的形式返回
    
        if ('HTTPS' === strtoupper($scheme)) {
            // SSL设置
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        }
    
        if (isset($data['option']['type']) && 'POST' === strtoupper(trim($data['option']['type']))) {
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST"); // 设置为POST请求
            if (isset($data['data']) && is_array($data['data'])) {
                $data_string =  json_encode($data['data']);
                curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                    'Content-Type: application/json',
                    'Content-Length: ' . strlen($data_string))
                );
                curl_setopt($curl, CURLOPT_POSTFIELDS,$data_string);
            }
        } else {
            /* if (isset($data['data']) && is_array($data['data'])) {
                $query = http_build_query($data['data']);
                $url  .= '?' . $query;
            } */
        }
        set_time_limit(0);
        $response = curl_exec($curl);
        curl_close($curl);
        //print_r($response);
        if (false === $response) {
            self::$_errorMessage = 'Service_GetDHLInfoProcess::http()执行curl_exec()时发生异常';
        }
    
        return $response;
    }
 }
