<?php

/**
 *  [冻死迎风站]--[饿死不说么吃饭]
 *  =========================================================================@_@=====================================@_@
 * @desc    4PX 递四方渠道对接
 * @author  leeong <9387524@gmail.com>
 * @version 1.0.0
 */
class Service_FourpxWebService extends Common_Service
{
    private $operationSoap;
    private $toolSoap;
    private $errorMsg;
    private $pxSmCode = array(
        '4PX-LYT_GH' => 'A6',
        '4PX-EU_PACKET' => 'DS',
        '4PX-RU_POST-LINK_RMAIL' => 'BA',
        '4PX-HKDHL' => 'A1',
        '4PX-Singapo_SPack_IMAIR' => 'B1',
        '4PX-SG_ordinary_mail+' => 'CQ',
    );

    // 特殊渠道
    private $specSmCode = array('4PX-EU_PACKET', '4PX-RU_POST-LINK_RMAIL', '4PX-Singapo_SPack_IMAIR', '4PX-SG_ordinary_mail+');

    // 在线订单操作(1.创建订单 2.预报订单 3.创建并预报订单 4.修改订单 5.删除订单 6.查询订单)
    private $ordersOperationUrl = 'http://api.4px.com/OrderOnlineService.dll?wsdl';
    //在线订单操作工具(1.运费试算 2.查询轨迹 3.申请拦截 4.查询跟踪号 5.打印标签)
    private $ordersToolUrl = 'http://api.4px.com/OrderOnlineToolService.dll?wsdl';
    //获取打印数据
    private $getPdfUrl = 'http://aeapi.4px.com/label/printOrder';

    //密钥
    private $authToken = '2785FEA7FB95A55446E1B3325D7E52BE';
    // private $authToken = 'CD29AD1E6703C0DB57271CA42B87A7D9';

    private $operationArr = array(
        'createOrderService',
        'preAlertOrderService',
        'createAndPreAlertOrderService',
        'modifyOrderService',
        'removeOrderService',
        'findOrderService',
    );
    private $toolArr = array(
        'chargeCalculateService',
        'cargoTrackingService',
        'cargoHoldService',
        'findTrackingNumberService',
        'findLabelDataService',
        'propsPrintLabelPng'
    );

    public function __construct() {
        //测试链接
        try {
            $this->operationSoap = new SoapClient($this->ordersOperationUrl,array(true));
            $this->toolSoap = new SoapClient($this->ordersToolUrl, array(true));
        } catch (Exception $e) {
            $this->errorMsg = $e->__toString();
        }
    }

    public function __call($name, $arguments) {
        throw new Exception('当前没有此服务方法，请检查方法名是否有误');
    }

    // 对象转数组
    protected function outputObject($obj) {
        $arr = is_object($obj)? get_object_vars($obj) : $obj;
        $result = array();
        foreach ($arr as $key => $val) {
            $val = (is_array($val)) || is_object($val) ? $this->outputObject($val) : $val;
            $result[$key] = $val;
        }
        return $result;
    }

    //数组转对象
    protected function returnObject($arr) {
        $clsName = new stdClass();
        foreach($arr as $key => $value) {
            $clsName->$key = $value;
        }
        return $clsName;
    }

    //合并数组
    protected function mergeArray($arrs0, $arrs1) {
        foreach($arrs0 as $key0 => $value0) {
            if(isset($arrs1[$key0]) && !empty($arrs1[$key0])) {
                $arrs0[$key0] = $arrs1[$key0];
            } else {
                unset($arrs0[$key0]);
            }
        }
        return $arrs0;
    }

    protected function simplest_xml_to_array($xmlstring) {
        return json_decode(json_encode((array) simplexml_load_string($xmlstring)), true);
    }
    // 创建订单 需重新测试 参考创建和预报接口
    public function createOrderService($orderCode) {
        // 订单信息
        $orderRow = Service_Orders::getByField($orderCode,'order_code',"*");

        // 收货地址
        $orderReceiveAddress = Service_OrderAddressBook::getByCondition(array('order_code'=>$orderCode,'oab_type'=>'0'),"*");

        // 收货国家
        $reCountry = Service_Country::getByField($orderReceiveAddress[0]['oab_country_id'],"country_id","*");
        $orderProduct = Service_OrderProduct::getByCondition(array('order_code'=>$orderCode),"*");
        $orderInfo = array();
        $orderInfo['orderNo'] = $orderCode;             //订单号
        $orderInfo['productCode'] = $this->pxSmCode[trim($orderRow['sm_code'])];   //4PX渠道代码
        $orderInfo['destinationCountryCode'] = $reCountry['country_code'];  //目的国家二字码
        if (in_array($orderRow['sm_code'], $this->specSmCode)) {
            $grossWeight= Service_Orders::calculateWeight($orderRow['order_code']);
            $orderInfo['customerWeight'] = sprintf('%.2f',$grossWeight); //客户重量
        }
        $orderInfo['transactionId'] = $orderRow['reference_no']; //订单交易号 交易 ID
        $orderInfo['consigneeName'] = $orderReceiveAddress[0]['oab_firstname'] . ' ' . $orderReceiveAddress[0]['oab_lastname'];
        $orderInfo['street'] = trim($orderReceiveAddress[0]['oab_street_address1'] . ' ' . $orderReceiveAddress[0]['oab_street_address2']);
        $orderInfo['city'] = $orderReceiveAddress[0]['oab_city'];
        $orderInfo['stateOrProvince'] = $orderReceiveAddress[0]['oab_state'];
        $orderInfo['consigneeTelephone'] = $orderReceiveAddress[0]['oab_cell_phone'];
        foreach($orderProduct as $key=>$val){
            $p = Service_Product::getByField($val['product_id'],"product_id","*");
            $declareInvoice['eName'] = $p['hs_goods_name'];
            $declareInvoice['declareUnitCode'] = 'PCE';
            $declareInvoice['declarePieces'] = $val['op_quantity'];
            $declareInvoice['unitPrice'] = $val['op_declared_value'];
            $declareInvoice['name'] = empty($val['product_title_en'])?$p['product_title']:$val['product_title_en'];
            $declareInvoice['hscode'] = $p['hs_code'];
            $orderInfo['declareInvoice'] = $declareInvoice;
        }

        $temp = array(
            'arg0' => $this->authToken,
            'arg1' => $this->returnObject($orderInfo)
        );
        return $this->push(__FUNCTION__, $temp);
    }

    // 创建并预报订单
    public function createAndPreAlertOrderService($orderCode) {
        // 订单信息
        $orderRow = Service_Orders::getByField($orderCode,'order_code',"*");

        // 收货地址
        $orderReceiveAddress = Service_OrderAddressBook::getByCondition(array('order_code'=>$orderCode,'oab_type'=>'0'),"*");

        // 收货国家
        $reCountry = Service_Country::getByField($orderReceiveAddress[0]['oab_country_id'],"country_id","*");
        $orderProduct = Service_OrderProduct::getByCondition(array('order_code'=>$orderCode),"*");
        $orderInfo = array();
        $orderInfo['orderNo'] = $orderCode;             //订单号   todo
        $orderInfo['productCode'] = $this->pxSmCode[trim($orderRow['sm_code'])];   //4PX渠道代码    todo
        $orderInfo['destinationCountryCode'] = $reCountry['country_code'];  //目的国家二字码
        if (in_array($orderRow['sm_code'], $this->specSmCode)) {
               $grossWeight= Service_Orders::calculateWeight($orderRow['order_code']);
            $orderInfo['customerWeight'] = sprintf('%.2f',$grossWeight); //客户重量
            if($orderRow['sm_code']=='4PX-SG_ordinary_mail+'){
                if($orderInfo['customerWeight']<=0.07){
                     $orderInfo['customerWeight'] = 0.07;
                }
            }
        }
        if($orderRow['sm_code']=='4PX-HKDHL'){
            $senderCondtion=array(
                'customer_code'=>$orderRow['customer_code'],
                'cab_type'=>2,
            );
            $senderAddress=Service_CustomerAddressBook::getByCondition($senderCondtion);
            if(empty($senderAddress)){
                return $orderRow['customer_code'].'客户发件人信息为空';
            }
            $orderInfo['shipperCompanyName']=$senderAddress[0]['cab_company'];
            $orderInfo['shipperName']=$senderAddress[0]['cab_firstname'].$senderAddress[0]['cab_lastname'];
            $orderInfo['shipperAddress']=$senderAddress[0]['cab_street_address1'].$senderAddress[0]['cab_street_address2'];
            $orderInfo['shipperTelephone']=$senderAddress[0]['cab_cell_phone'];
            $orderInfo['shipperPostCode']=$senderAddress[0]['cab_postcode'];
            $orderInfo['shipperFax']=$senderAddress[0]['cab_postcode'];
        }
        if ($orderRow['sm_code'] == '4PX-LYT_GH') {
            if ($orderRow['is_pod'] == 1) {
                $orderInfo['needPOD'] = 'Y';
            }else {
                $orderInfo['needPOD'] = 'N';
            }
        }
         if($orderRow['sm_code']=='4PX-RU_POST-LINK_RMAIL'){
                $orderInfo['mctCode']='5';
        }
       if($orderRow['sm_code']=='4PX-Singapo_SPack_IMAIR'){
                $orderInfo['trackingNumber']=$orderRow['ref_tracking_number'];
        }
        $orderInfo['transactionId'] = $orderRow['reference_no']; //订单交易号 交易 ID
        $orderInfo['consigneeName'] = $orderReceiveAddress[0]['oab_firstname'] . ' ' . $orderReceiveAddress[0]['oab_lastname'];
        $orderInfo['street'] = trim($orderReceiveAddress[0]['oab_street_address1'] . ' ' . $orderReceiveAddress[0]['oab_street_address2']);
        $orderInfo['city'] = $orderReceiveAddress[0]['oab_city'];
        $orderInfo['stateOrProvince'] = $orderReceiveAddress[0]['oab_state'];
        $orderInfo['consigneePostCode'] = $orderReceiveAddress[0]['oab_postcode'];
        $orderInfo['consigneeTelephone'] = $orderReceiveAddress[0]['oab_cell_phone'];
        foreach($orderProduct as $key=>$val){
            $p = Service_Product::getByField($val['product_id'],"product_id","*");
            $declareInvoice['eName'] =  empty($val['product_title_en'])?$p['product_title']:$val['product_title_en'];
			//$p['product_title_en']?$p['product_title_en']:'fw';  //todo
            $declareInvoice['declareUnitCode'] = 'PCE';
            $declareInvoice['declarePieces'] = $val['op_quantity'];
            $declareInvoice['unitPrice'] = round($val['op_purpose_declared_value'], 2);
            $declareInvoice['name'] = empty($val['product_title_en'])?$p['product_title']:$val['product_title_en'];
            $declareInvoice['hscode'] = $p['hs_code'];
            if($orderRow['sm_code']=='4PX-HKDHL'){
                $declareInvoice['cName']=$p['hs_goods_name'];
            }
           
            //是否带电池
            if ($p['with_battery'] == 1) {
                $declareInvoice['hasbattery'] = 'Y';
            }
            $orderInfo['declareInvoice'][] = $declareInvoice;
        }
        $temp = array(
            'arg0' => $this->authToken,
            'arg1' => $this->returnObject($orderInfo)
        );
        return $this->push(__FUNCTION__, $temp);
    }

    // 查询轨迹
    public function cargoTrackingService($orderCode) {
        $orderRow = Service_Orders::getByField($orderCode,'order_code',"*");
        if($orderRow['ref_tracking_number']=="") return false;
        $temp = array(
            'arg0' => $this->authToken,
            'arg1' => $orderRow['ref_tracking_number']
        );
        return $this->push(__FUNCTION__, $temp);
    }

    // 查询标签
    public function findLabelDataService($orderCode) {
        $orderRow = Service_Orders::getByField($orderCode,'order_code',"*");
        if($orderRow['ref_tracking_number']=="") return false;
        $temp = array(
            'arg0' => $this->authToken,
            'arg1' => $orderRow['ref_tracking_number']
        );
        return $this->push(__FUNCTION__, $temp);
    }

    // 查询跟踪号
    public function findTrackingNumberService($orderCode){
        $temp = array(
            'arg0' => $this->authToken,
            'arg1' => $orderCode
        );
        return $this->push(__FUNCTION__, $temp);
    }

    public function getPdfByOrderCode($orderCode){
        $result = array(
                'status' => 0,
                'message' => '操作失败'
        );
        $orderRow = Service_Orders::getByField($orderCode,'order_code',"*");
        if($orderRow['ref_tracking_number']=="") return false;
        if (in_array($orderRow['sm_code'], $this->specSmCode)&&$orderRow['sm_code']!='4PX-EU_PACKET') {
            $type = 3;
        } else {
            $type = 1;
        }
            $xml = '<?xml version="1.0" encoding="utf-8" ?>' .
                "<labelRequest>" .
                "<authToken>" . $this->authToken . "</authToken>".
                "<printConfig>" .
                "<labelFormat>pdf</labelFormat>" .
                "<labelType>" . $type . "</labelType>" .
                "<labelSize>label_80x90</labelSize>";
            if ($type == 3) {
                $xml .= "<declarationLabel>Y</declarationLabel>";
            }
            $xml .="</printConfig>" .
                "<trackingNumbers>" .
                "<trackingNumber>" . $orderRow['ref_tracking_number'] . "</trackingNumber>" .
                "</trackingNumbers>" .
                "</labelRequest>";

            $str = "token=".$this->authToken."&request=".$xml;
            //第一种发送方式，也是推荐的方式：
            $header[] = "Content-type:application/x-www-form-urlencoded";
            $ch = curl_init ($this->getPdfUrl);
            curl_setopt($ch, CURLOPT_URL, $this->getPdfUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $str);
            $response = curl_exec($ch);
            if(curl_errno($ch)){
                $result['message'] = curl_error($ch);
                curl_close($ch);
                return $result;
            }
            curl_close($ch);
            $response = $this->simplest_xml_to_array($response);
            if ($response['success'] == false) {
                $result['message'] = $response['errorCode'] . ":" . $response['errorMsg'];
                return $result;
            } elseif($response['success'] == true) {
                $result['status'] = 1;
                $result['message'] = '订单' . $orderCode . "获取面单打印数据成功";
                $result['url'] = $response['datas']['data'];
            }
            // 写入pdf文件
            $fileContent = file_get_contents($result['url']);
            if($fileContent!=""){
                $labelContent=array(
                    'order_code'=>$orderCode,
                    'ol_content'=>  base64_encode($fileContent),
                    'ol_time'=>date('Y-m-d H:i:s')
                );
                $id=Service_OrdersLabel::add($labelContent);
                $result['lable_content']=$labelContent;
            }
        return $result;
    }

    // 推送API
    protected function push($method, $arr) {
        $demo = array(
            'status' => 0,
            'message' => '推送失败'
        );
        if (in_array($method, $this->operationArr)) {
            $result = $this->operationSoap->__soapCall($method, array($arr));
        } elseif (in_array($method, $this->toolArr)) {
            $result = $this->toolSoap->__soapCall($method, array($arr));
        }
        if (!$result) {
            return $demo;
        }
        return $this->outputObject($result);
    }

    public function __get($name) {
        if ($this->$name) {
            return $this->$name;
        } else {
            return '';
        }
    }
}
