<?php
class Service_KFiveApiProcess extends Common_Service{
	private $orderInfo = '';
	private $operationSoap;
	private $otherSoap;
	public  $errorMsg;
	private $trackLanguage = 'zh';
	
	//在线订单操作
	private $ordersOperationUrl = 'http://218.17.211.21:9999/services/OrderInterfaceService?Wsdl';
	
	//在线其他操作,(获取轨迹)
	private $trackGetUrl = 'http://218.17.211.21:9999/services/APITrack?Wsdl';
	
	//客户id
	private $clientId = 'BHMY4516';
	
	//秘钥
	private $authToken = 'Fw71D4k0fI5bu1gre4Ca';
	
	//在线订单操作方法
	private $operationArr = array(
		'submitOrderForecast',//提交并预报订单
		'submitOrder',//提交订单
		'searchChannel',//获取渠道
		'retrieveGetBillid',//重新获取单号
		'getBillidByCorpBillid',//根据公司单号获取服务商单号
		'getOrderPrintLabel',//获取打印标签
		'getTransBillidByCorpBillid',//根据订单号获取运单号和转单号
	);
	//在线其他操作方法
	private $otherArr = array(
	    'getTrack'//根据追踪号获取轨迹信息
	);
	
	//构造函数
	public function __construct(){
		try{
			$this->operationSoap = new SoapClient(null, array('location' =>$this->ordersOperationUrl,'uri'=>$this->ordersOperationUrl));
			$this->otherSoap = new SoapClient(null, array('location' =>$this->trackGetUrl,'uri'=>$this->trackGetUrl));
		}catch(Exception $e){
			$this->errorMsg = $e->__toString();
		}
	}
	//调用不存在的方法，报错提示
	public function __call($name, $arguments) {
        throw new Exception('当前没有此服务方法，请检查方法名是否有误');
    }
	
	// 对象转数组
    protected function objectTransferArray($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->objectTransferArray($val) : $val;
            $result[$key] = $val;
        }
        return $result;
    }

    //数组转对象
    protected function arrayTransferObject($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;
    }
	//将简单xml文件转换成数组
	protected function simplest_xml_to_array($xmlstring) {
        return json_decode(json_encode((array) simplexml_load_string($xmlstring)), true);
    }
	
	public function submitOrderForecast($orderRow){
		//订单信息
		$this->orderInfo = $orderRow;
		// 收货地址
        $orderReceiveAddress = Service_OrderAddressBook::getByCondition(array('order_code'=>$orderRow['order_code'],'oab_type'=>'0'),"*");
		//收货国家
		$reCountry = Service_Country::getByField($orderReceiveAddress[0]['oab_country_id'],"country_id","*");
		$orderProduct = Service_OrderProduct::getByCondition(array('order_code'=>$orderRow['order_code']),"*");
		$grossWeight= Service_Orders::calculateWeight($orderRow['order_code']);
        $orderRow['customerWeight'] = sprintf('%.3f',$grossWeight); //客户重量
		$withBattery = 0;
	    foreach($orderProduct as $value){
			$productInfo = Service_Product::getByField($value['product_id'],"product_id","*");
					$xmlCenterPart .= '<DeclareInvoice>'.
									  '<itemcont>'.$productInfo['product_title'].'</itemcont>'.//申报品名
									  '<itemcustoms>'.$value['product_title_en'].'</itemcustoms>'.//申报英文品名
									  '<itempeihuo></itempeihuo>'.//配货信息
									  '<itemvalue>'.round(($value['op_purpose_declared_value']*$value['op_quantity']),2).'</itemvalue>'.//申报价值
									  '<itemnum>'.$value['op_quantity'].'</itemnum>'.//申报数量
									  '<itemprodno>'.$productInfo['hs_code'].'</itemprodno>'.//海关货物编号
									  '<itemphnote></itemphnote>'.//配货备注
									  '<itemunit>USD</itemunit>'.//单位
									  '<itemsbprice>'.$value['op_purpose_declared_value'].'</itemsbprice>'.//申报单价
									  '<itemimgurl></itemimgurl>'.
									  '<itemweight1>'.round(($productInfo['product_weight']*$value['op_quantity']),3).'</itemweight1>'.
									  '<itemsku>'.$productInfo['product_sku'].'</itemsku>'.//产品sku
								  '</DeclareInvoice>';
			if($productInfo['with_battery'] == 1){
				$withBattery = 1;
			}
		}	
		//向服务商发送何种运输方式代码
		$channelid = ($orderRow['sm_code'] == 'DHL-BH03') ? 'DHL03' : 'POSTNL5';
		$xmlHeadPart = '<?xml version="1.0" encoding="utf-8"?>'.
					'<CreateAndPreAlertOrderService>'.
						'<authtoken>'.$this->authToken.'</authtoken>'.
						'<clientid>'.$this->clientId.'</clientid>'.
						'<CreateAndPreAlertOrderRequestArray>'.
							'<CreateAndPreAlertOrderRequest>'.
								'<billid></billid>'.
								'<refernumb>'.$orderRow['order_code'].'</refernumb>'.//订单号
								'<channelid>'.$channelid.'</channelid>'.//运输方式,运输方式为DHL-BH03强制改成DHL03发送服务商
								'<recname>'.$orderReceiveAddress[0]['oab_firstname'].$orderReceiveAddress[0]['oab_lastname'].'</recname>'.//收件人名
								'<recaddr1>'.$orderReceiveAddress[0]['oab_street_address1'].'</recaddr1>'.//收件人地址1
								'<recaddr2>'.$orderReceiveAddress[0]['oab_street_address2'].'</recaddr2>'.//收件人地址2
								'<rectel>'.$orderReceiveAddress[0]['oab_cell_phone'].'</rectel>'.//收件人电话
								'<reccorp>'.$orderReceiveAddress[0]['oab_company'].'</reccorp>'.//收件人公司名称
								'<recprovince>'.$orderReceiveAddress[0]['oab_state'].'</recprovince>'.//收件人省(州)
								'<reccity>'.$orderReceiveAddress[0]['oab_city'].'</reccity>'.//收件人城市
								'<recpost>'.$orderReceiveAddress[0]['oab_postcode'].'</recpost>'.//收件人邮编
								'<recemail>'.$orderReceiveAddress[0]['oab_email'].'</recemail>'.//收件人电子邮箱
								'<country>'.$reCountry['country_code'].'</country>'.//国检二字码
								'<weight>'.$orderRow['customerWeight'].'</weight>'.//总重量（kg）
								'<battery>'.$withBattery.'</battery>'.
								'<DeclareInvoiceArray>';
	   				
		$xmlFootPart		   = '</DeclareInvoiceArray>'.
							'</CreateAndPreAlertOrderRequest>'.
						'</CreateAndPreAlertOrderRequestArray>'.
					'</CreateAndPreAlertOrderService>'; 
	    $xml = $xmlHeadPart.$xmlCenterPart.$xmlFootPart;
		//header("Content-type:text/xml");		
		//echo $xml.'<br/>';
		//echo '<pre>';
		//var_dump($this->simplest_xml_to_array($xml));
		//echo '</pre>';
		return $this->push(__function__,$xml);
	}
	
	public function getOrderPrintLabel($orderRow){
		//订单信息
		$this->orderInfo = $orderRow;
		//查询订单跟踪号
		$orderRow = Service_Orders::getByField($orderRow['order_code'],'order_code',"*");
		$xml = '<?xml version= "1.0" encoding= "utf-8"?>'.
					'<GeOrdertPrintServiceRequest>'.
						'<authtoken>'.$this->authToken.'</authtoken>'.
						'<clientid>'.$this->clientId.'</clientid>'.
						'<corpbillid>'.$orderRow['ref_tracking_number'].'</corpbillid>'.
						'<url>http://k5.kingtrans.cn/</url>'.//接口根地址
						'<paper>100-100</paper>'.//打印纸张
						'<content>1,2,3</content>'.
						'<ifprinttime>0</ifprinttime>'.
					'</GeOrdertPrintServiceRequest>';
		//echo $xml.'<br/>';
		return $this->push(__function__,$xml);
	}
	
	public function getTransBillidByCorpBillid($orderRow){
		//订单信息
		$this->orderInfo = $orderRow;
		//查询订单跟踪号
		$orderRow = Service_Orders::getByField($orderRow['order_code'],'order_code',"*");		
		//根据服务商系统单号获取获取运单号和转单号
		$xml = '<?xml version="1.0" encoding="utf-8"?>'.
    		  		'<GetBillidServiceRequest>'.
    					'<authtoken>'.$this->authToken.'</authtoken>'.
    					'<clientid>'.$this->clientId.'</clientid>'.
    					'<GetBillidArray>'.
    						'<corpbillid>'.$orderRow['agent_mailno'].'</corpbillid>'.
    					'</GetBillidArray>'.
    				'</GetBillidServiceRequest>';
		//echo '<pre>';
		//var_dump($this->simplest_xml_to_array($xml));
		//echo '</pre>';
		return $this->push(__function__,$xml);
	}
	
	public function getTrack($orderRow){
	    //订单信息
	    $this->orderInfo = $orderRow;
	    //查询订单跟踪号
	    $orderRow = Service_Orders::getByField($orderRow['order_code'],'order_code',"*");
	    $shipOrderRow = Service_ShipOrder::getByField($orderRow['order_code'],'order_code',"*");
	    if($orderRow['ref_tracking_number'] != $shipOrderRow['tracking_number']){
	        $trackingNumber = $shipOrderRow['tracking_number'];
	    }else{
	        $trackingNumber = $orderRow['ref_tracking_number'];
	    }
	    //根据追踪号获取轨迹信息
	    $xml = '<?xml version="1.0" encoding="utf-8"?>'.
                    '<GeTrackServiceRequest>'.
                        '<authtoken>'.$this->authToken.'</authtoken>'.
    					    '<clientid>'.$this->clientId.'</clientid>'.
                        	'<billid>'.$trackingNumber.'</billid>'.
                        	'<language>'.$this->trackLanguage.'</language>'.
                     '</GeTrackServiceRequest>';
	    //echo '<pre>';
	    //var_dump($this->simplest_xml_to_array($xml));
	    //echo '</pre>';
	    return $this->push(__function__,$xml);
	}
	
	//创建订单返回处理
	private function submitOrderForecastResultProcess($result,$orderInfo){
		$response = array(
            'status' => 0,
            'message' => ''
        );
		if(preg_match('/执行成功/',$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['Ack'])){
		    if($orderInfo['sm_code'] == 'DHL-BH03'){
		        $updateOrder = array(
		            'ref_tracking_number'=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['billid'],//服务商单号,追踪号
		            //''=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['refnumb'],//参考号,客户订单号
		            'agent_mailno'=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['corpbillid'],//系统单号,单据编号,临时存放至agent_mailno字段
		            //''=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['channelid'],//运输方式如：DHL,UPS 等
		            //''=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['curflag'],//订单当前状态(0-待检查,1-已确认,2-待确认,3-已预报,4-已收货,5-已发货,6-已退货,7-已删除,8-缺货)
		            //'sync_status'=>'1'
		        );
		    }else{
		        $updateOrder = array(
		            'ref_tracking_number'=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['billid'],//服务商单号,追踪号
		            //''=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['refnumb'],//参考号,客户订单号
		            //'agent_mailno'=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['corpbillid'],//系统单号,单据编号,临时存放至agent_mailno字段
		            //''=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['channelid'],//运输方式如：DHL,UPS 等
		            //''=>$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['curflag'],//订单当前状态(0-待检查,1-已确认,2-待确认,3-已预报,4-已收货,5-已发货,6-已退货,7-已删除,8-缺货)
		            //'sync_status'=>'1'
		        );
		    }
			
			$orderLog = array(
                    'order_id' => $orderInfo['order_id'],
                    'order_code' => $orderInfo['order_code'],
                    'ol_type' => '1',
                    'order_status_from' => $orderInfo['order_status'],
                    'order_status_to' => $orderInfo['order_status'],
                    'ol_add_time' => date("Y-m-d H:i:s"),
                    'user_id' => 0,
                    'ol_comments' => $orderInfo['sm_code'].'自动取服务商单号'
                );
			//写入日志信息
            Service_OrderLog::add($orderLog);
			//更新数据库
			Service_Orders::update($updateOrder, $orderInfo['order_id'], "order_id");
			$response['status']  = 1;
			$response['message'] = "订单" . $orderInfo['order_code'] . "获取单号" . $result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['OrderItem']['billid'] . "成功\n";
		}else{
			$response['message'] = '创建并预报订单失败，'.$result['CreateOrderServiceResponseArray']['CreateOrderServiceResponse']['Error'];
			//防止正常多次请求服务商单号记录为错误日志，判断orders表中ref_tracking_number字段是否为空
			$errorLog = array(
                        'order_code' => $orderInfo['order_code'],
                        'sm_code' => $orderInfo['sm_code'],
                        'content' => $response['message'],
                    );
			if(empty($orderInfo['ref_tracking_number'])){
			    $errorLogId = Service_TrackingErrorLog::add($errorLog);
			}
		}
		
		return $response;
	}
	
	//标签返回处理
	private function getOrderPrintLabelResultProcess($result,$orderInfo){
		$response = array(
            'status' => 0,
            'message' => ''
        );
		$file = APPLICATION_PATH . '/../data/pdf/KFive/' . $orderInfo['order_code'] . '.pdf';
		if($result['Ack'] == 'true'){
			$response['status'] = 1;
			$response['message'] = '订单' . $orderInfo['order_code'] . "获取面单打印数据成功";
		}else{
			$response['message'] = '标签获取失败，'.$result['Errror'];
		}
		//远程读取PDF文件
		if(!empty($result['printurl'])){
			$fileContent = file_get_contents($result['printurl']);
		}
		//PDF文件不存在则创建
		if(!file_exists($file)){
			if('' != $fileContent){
				// 没有文件夹则创建
				$path_dir = APPLICATION_PATH . '/../data/pdf';
				if(!is_readable($path_dir)){
					is_file($path_dir) or mkdir($path_dir,0755);
				}
				$path_dir = APPLICATION_PATH . '/../data/pdf/KFive';
				if(!is_readable($path_dir)){
					is_file($path_dir) or mkdir($path_dir,0755);
				}
				$fp=fopen($file, "w+");
				file_put_contents($file,$fileContent);
				fclose($fp);
				Service_OrdersLabel::add(array(
					'order_code'=>$orderInfo['order_code'],
					'ol_content'=>  base64_encode($fileContent),
					'ol_time'=>date('Y-m-d H:i:s')
				));
			}
		}
		return $response;
	}
	
	//查询运单号和转单号返回处理
	private function getTransBillidByCorpBillidResultProcess($result,$orderInfo){
		//查询订单跟踪号
		$orderRow = Service_Orders::getByField($orderInfo['order_code'],'order_code',"*");
		$response = array(
            'status' => 0,
            'message' => ''
        );
		if($result['Ack'] == 'true'){
			$updateOrder = array(
				'ref_tracking_number'=>$result['ReBillidArr']['transbillid'],//获取转单号
				'agent_mailno'=>''//获取转单号成功后，跟踪号不一致，删除临时记录的接口方系统单号
			);
			//跟踪号不一致则更新覆盖
			if($orderRow['ref_tracking_number'] !== $updateOrder['ref_tracking_number']){
				$orderLog = array(
                    'order_id' => $orderInfo['order_id'],
                    'order_code' => $orderInfo['order_code'],
                    'ol_type' => '1',
                    'order_status_from' => $orderInfo['order_status'],
                    'order_status_to' => $orderInfo['order_status'],
                    'ol_add_time' => date("Y-m-d H:i:s"),
                    'user_id' => 0,
                    'ol_comments' => '服务商单号由'.$orderRow['ref_tracking_number'].'变为'.$updateOrder['ref_tracking_number']
                );
				//写入日志信息
				Service_OrderLog::add($orderLog);
				//更新数据库
				Service_ShipOrder::update(array('tracking_number'=>$updateOrder['ref_tracking_number']), $orderInfo['order_code'] ,'order_code');
				unset($updateOrder['ref_tracking_number']);
				Service_Orders::update($updateOrder, $orderInfo['order_id'], "order_id");
			}
			$response['status']  = 1;
			$response['message'] = "订单" . $orderInfo['order_code'] . "获取运单号或转单号成功\n";
		}else{ 
			$response['message'] = '根据订单号获取运单号和转单号失败,'.$result['Errror'];
			$errorLog = array(
			    'order_code' => $orderInfo['order_code'],
			    'sm_code' => $orderInfo['sm_code'],
			    'content' => $response['message'],
			);
			$errorLogId = Service_TrackingErrorLog::add($errorLog);
		}
		return $response;
	}
	
	//查询获取轨迹信息处理
	private function getTrackResultProcess($result,$orderInfo){
	    $response = array(
	        'status' => 0,
	        'message' => ''
	    );
	    if($result['Ack'] == 'true'){
            foreach($result['Trackitem'] as $trackitem){
			    if(empty($trackitem['place']))continue;
                $condtion=array(
                    'order_code'=>$orderInfo['order_code'],
                    'sot_location'=>$trackitem['place'],
					'sot_description'=>$trackitem['intro']
                );
                $exitTracking=  Service_ShipOrderTracking::getByCondition($condtion,'count(*)');
                if(!$exitTracking){
                    $shipTracking=array(
                        'order_code'=>$orderInfo['order_code'],
                        'sot_location'=>$trackitem['place'],
                        'sot_add_time'=>$trackitem['sdate'],
                        //'sot_time_offset'=>'',
                        'warehouse_id'=>$orderInfo['warehouse_id'],
                        'sot_description'=>$trackitem['intro'],
                        //'sot_info_type'=>'',
                        'tracking_number'=>$result['Track']['transbillid'],
                        'ref_tracking_number'=>$orderInfo['ref_tracking_number'],
						'status_desc'=>'物流完成'
                    );
                    Service_ShipOrderTracking::add($shipTracking);
                }
            }
            //检测签收人字段是否为空，不为空，则表示已签收
            if(!empty($result['Track']['deliverer'])){
                $updateOrder = array(
                    'order_status' => 13,
                    'sync_status'=>'1'
                );
                $orderLog = array(
                    'order_id'=>$orderInfo['order_id'],
                    'order_code'=>$orderInfo['order_code'],
                    'ol_type'=>'1',
                    'order_status_from'=>$orderInfo['order_status'],
                    'order_status_to'=>13,
                    'ol_add_time'=>date("Y-m-d H:i:s"),
                    'user_id'=>0,
                    'ol_comments'=>'自动取运输轨迹,已签收'
                );
                Service_Orders::update($updateOrder, $orderInfo['order_code']);
                Service_OrderLog::add($orderLog);
            }
            $response['status']  = 1;
            $response['message'] = "订单" . $orderInfo['order_code'] . "获取物流轨迹成功\n";
	    }else{
	        $response['message'] = '根据运单号或转单号查询物流轨迹失败,'.$result['Error'];
	        $errorLog = array(
	            'order_code' => $orderInfo['order_code'],
	            'sm_code' => $orderInfo['sm_code'],
	            'content' => $response['message'],
	        );
	        $errorLogId = Service_TrackingErrorLog::add($errorLog);
	    }
	    return $response;
	}
	
	// 推送API
    protected function push($method, $arr) {
        $response = array(
            'status' => 0,
            'message' => '推送失败'
        ); 
        if (in_array($method, $this->operationArr)) {
            $result = $this->operationSoap->__soapCall($method, array($arr));
        }elseif(in_array($method,$this->otherArr)){
            $result = $this->otherSoap->__soapCall($method, array($arr));
        }
        if (!$result) {
            return $response;
        }
		$result = $this->simplest_xml_to_array(is_array($result) || is_object($result) ? $this->objectTransferArray($result) : $result);
		//echo '<pre>';
		//var_dump($result);
		//echo '</pre>';
		$resultProcessFun = $method.'ResultProcess';
		return $this->$resultProcessFun($result,$this->orderInfo);
    }
}