<?php
/**
 * 2017-02-03
 * 费用相关接口
 * 
 */
class Api_ServiceForCost
{
    protected $_customerId = null;
    
    protected $_customer = null;

    protected $_targetCustomerCode = null;//认证用户想要操作的客户

    protected $_token = null;

    protected $_key = null;

    protected $_auth = false;

    protected $_error = null;    

    protected $_date = null;

    protected $_parameterArr = array();//将传递过来的对象转为数组存储
    

    private function _init ($headerRequest) {
        $this->_customerId = (string) $headerRequest['customerCode'];
        $this->_targetCustomerCode = (string) $headerRequest['operationCustomerCode'];
        $this->_token = (string) $headerRequest['appToken'];
        $this->_key = (string) $headerRequest['appKey'];
    }
    /**
     * @author william-fan
     * @todo Authenticate
     */
    private function authenticate(){
        $customer = Service_Customer::getByField($this->_customerId, 'customer_code');
        if (! $customer || $customer['customer_status'] != 2) {
            $this->_error[] = 'No Authority For ' . $this->_customerId . '.';
            return false;
        }

        $customerAuth = Service_CustomerApi::getByField($this->_customerId, 'customer_code');
        //判断授权用户的权限
        if ($customerAuth && $customerAuth['ca_token'] == $this->_token && $customerAuth['ca_key'] == $this->_key) {
            //因为是操作目标客户，客户信息要设成目标客户的
            if( $this->_targetCustomerCode !== null && $this->_targetCustomerCode !== '' ) {
                $rc = Service_CustomerRegister::getByCondition( array( 'customer_code' => $this->_targetCustomerCode, 'regis_customer_code' => $this->_customerId ) );
                if( empty( $rc ) ) {
                    $this->_error[] = '操作客户 ' . $this->_targetCustomerCode . ' 不属于你.';
                    $path = APPLICATION_PATH.'/../data/log/888.txt';
                    file_put_contents($path, var_export($this->_targetCustomerCode,true), FILE_APPEND);
                    return false;
                }

                $customer = Service_Customer::getByField($this->_targetCustomerCode, 'customer_code');
                if( empty( $customer ) ) {
                    $this->_error[] = '操作客户 ' . $this->_targetCustomerCode . ' 不存在.';
                    return false;
                }
                $this->_customerId = $this->_targetCustomerCode;//将用户信息设成目标客户的
            }
            $this->_customer = $customer;
            $this->_auth = true;
            return true;
        } else {
            $this->_error[] = 'App Token/App Key Not match for ' . $this->_customerId . '.';
            return false;
        }
    }
	/**
	 * @todo 写日志
	 */
    private function logError ($error) {
        $logger = new Zend_Log();
        $uploadDir = APPLICATION_PATH . "/../data/log/";
        $writer = new Zend_Log_Writer_Stream($uploadDir . 'api-cost.log');
        $logger->addWriter($writer);
        $logger->info(date('Y-m-d H:i:s') . ': ' . $error . " \n");
    }
    
	/**
	 * @author william-fan
	 * @todo 对wsdl 自动将多维数组转为一维数组的处理
	 */
    private function multiArr ($arr) {
        $return = array();
        if(is_array($arr)){
            $isMulti = true;
            foreach($arr as $k=>$v){
                if(!is_int($k)){
                    $isMulti = false;
                }
            }
            if(!$isMulti){
                $return[] = $arr;
            }else{
                $return = $arr;
            }             
        }else if(is_string($arr)){
            $return[] = $arr;
        }
        return $return;
    }
    
    /**
     * @author william-fam
     * @todo 公共方法
     */ 
    private function common($parameter) {
		// var_dump($parameter);exit;
        // 对象转数组		
        $this->_parameterArr = Common_Common::objectToArray($parameter);//对象转数组		 
        $headRequest = $this->_parameterArr['HeaderRequest'];
        $this->_init($headRequest);
        //print_r($this->_parameterArr);
        //$this->_token = $this->_parameterArr['appToken'];
        //file_put_contents('error002.txt', '00000221'.$this->_token.var_export($this->_parameterArr,true));
        $this->_date = date('Y-m-d H:i:s');
        //file_put_contents('common.txt', '00000221'.$this->_token.var_export($this->_parameterArr,true));
        
        $this->authenticate();
        /* exit;
        file_put_contents('error003.txt', '0000020000555'.var_export($this->_parameterArr,true));return; */
    }


    /* @todo:获取订单运费
     * @date:2017-02-03
     *
     */
    public  function getShippingFee( $parameter ) {
		$result = array('ask'=>'0','message'=>'','error'=>array());
		$uploadDir = APPLICATION_PATH . "/../data/log/test.log";
		//	file_put_contents($uploadDir ,print_r($parameter,1));
		//file_put_contents($uploadDir ,print_r($this->_parameterArr,1));
		$this->common($parameter);
        if ( !empty( $this->_error ) ) {
            $result['message'] = implode(',', $this->_error );
            return $result;
        }
		//file_put_contents($uploadDir ,print_r($this->_parameterArr,1));
        $param = $this->getShippingFeeParam();
 		if ( !empty( $this->_error ) ) {
             $result['message'] = Ec_Lang::getInstance()->translate( 'failure', 'en_US' );
             foreach( $this->_error as $value) {
                $result['error']['errorMessage'][] = $value;
             }
            return $result;
        }

        $objCalculate = new Common_CalculateShipping( $param );
        $cost = $objCalculate->getRate();
        if( $cost['state'] == 1 ) {
            $result['ask']      = 1;
            $result['message'] =Ec_Lang::getInstance()->translate( 'success', 'en_US' );
            //再返回一个美元
            $transAmount = Service_Currency::converByCode( $cost['data']['cost']['currency_code'], 'USD', $cost['data']['cost']['totalCost'] );
            $result['data'] = array(
                    //'actualWeight'                 => $param['weight'],
                    //'chargeableWeight'            => $cost['data']['cost']['weight'],
                    'amount'                        => $cost['data']['cost']['totalCost'],
                    'currencyCode'                 => $cost['data']['cost']['currency_code'],
                    'changeAmount'                 => $transAmount,
            );
        } else {
            $result['message'] = Ec_Lang::getInstance()->translate( 'failure', 'en_US' );
            $errorCodes = $objCalculate->getErrorCode();
            $translateCodes = $objCalculate->getTranslateCode();
            foreach( $errorCodes as $code ) {
                if( isset( $translateCodes[ $code ] ) ) {
                    if( $code == 7 ) {
                        $maxWeight = $objCalculate->getMaxWeight();
                        $result['error']['errorMessage'][] = '12|'.Ec_Lang::getInstance()->translate( $translateCodes[ $code ], 'en_US' ).$maxWeight;
                    } else {
                        $result['error']['errorMessage'][] = '12|'.Ec_Lang::getInstance()->translate( $translateCodes[ $code ], 'en_US' );
                    }
                } else {
                    $result['error']['errorMessage'][] = '12|'.$code;
                }
            }
        }
        return $result;
    }
    /* @todo 获取订单运费参数
     *
     */
    private function getShippingFeeParam() {
        $param  = array();
        $param['customerCode'] = $this->_customerId;
        $warehouseIsRight = $countryIsRight = $provinceIsRight  = false;
        $this->checkParam();
        if( !empty( $this->_error ) ) {
            return $param;
        }
        $warehouse = Service_Warehouse::getByField( $this->_parameterArr['shippingFeeInfo']['warehouseCode'], 'warehouse_code');
        if( empty( $warehouse ) ) {
            $this->_error[] = '12|'.Ec_Lang::getInstance()->translate( 'warehouseDoesNotExist', 'en_US' );
        } else {
            $param['warehouseId'] = $warehouse['warehouse_id'];
            $warehouseIsRight = true;
        }
        $hasShipMethod = false;
        $shipMethod = array();
        if( $warehouseIsRight ) {
            $shipMethods = Service_ShippingMethod::getByCondition(
                                    array(
                                        'warehouse_id' => $param['warehouse_id'],
                                        'sm_code' => $this->_parameterArr['shippingFeeInfo']['smCode']
                                    )
                          );
            if( empty( $shipMethods ) ) {
                $this->_error[] = '12|'.Ec_Lang::getInstance()->translate( 'transportDoesNotExist', 'en_US' );;
            } else {
                $hasShipMethod = true;
                $shipMethod = $shipMethods[0];
                $param['smCode'] = $this->_parameterArr['shippingFeeInfo']['smCode'];
            }
        }

        $country = array();
        $countryIsRight = false;
        if( empty( $this->_parameterArr['countryId'] ) ) {
            $this->_error[] = '12|'.Ec_Lang::getInstance()->translate( 'countryDoesNotExist', 'en_US' );
        } else {
            $param['countryId'] = $this->_parameterArr['countryId'];
            $countryIsRight = true;
        }

        $destination = ( $this->_parameterArr['shippingFeeInfo']['smCode'] == 'DGF-CARGO'
            && isset( $this->_parameterArr['shippingFeeInfo']['destination'] )
            && !is_null( $this->_parameterArr['shippingFeeInfo']['destination'] )
            && $this->_parameterArr['shippingFeeInfo']['destination'] !== '' ) ? $this->_parameterArr['shippingFeeInfo']['destination'] : '';

        if( $countryIsRight && $destination !== '' ) {
            $airCodeRow = Service_AirportCountryMap::getByCondition( array( 'country_code' => $this->_parameterArr['country_code'], 'airport_destination' => $destination ) );
            if( empty( $airCodeRow ) ) {
                $this->_error[] = '12|'.Ec_Lang::getInstance()->translate( 'airCodeDoesNotExist', 'en_US' );
            } else {
                $param['aircode'] = $airCodeRow[0]['airport_destination'];
            }
        }

        if( $countryIsRight ) {
            $cityName = isset( $this->_parameterArr['shippingFeeInfo']['cityName'] )
                        && $this->_parameterArr['shippingFeeInfo']['cityName'] !== ''
                        && !is_null( $this->_parameterArr['shippingFeeInfo']['cityName'] ) ? $this->_parameterArr['shippingFeeInfo']['cityName'] : '';

            if( $cityName !== '') {
                $city = Service_City::getByCondition( array( 'city_name'=> $cityName, 'country_id' => $param['countryId'] ) );
                if( empty( $city )  ) {
                    $this->_error[] = '12|'.Ec_Lang::getInstance()->translate( 'cityDoesNotExist', 'en_US' );
                } else {
                    $param['cityId'] = $city[0]['city_id'];
                }
            }
        }

        $postCode = ( isset( $this->_parameterArr['shippingFeeInfo']['postCode'] )
                      && $this->_parameterArr['shippingFeeInfo']['postCode'] !== ''
                      && !is_null( $this->_parameterArr['shippingFeeInfo']['postCode'] ) ) ? $this->_parameterArr['shippingFeeInfo']['postCode'] : '';

        if( $postCode !== '' ) {
            $param['postcode'] = $this->_parameterArr['shippingFeeInfo']['postCode'];
        }
        if( Service_CustomerProcess::$HuanQiu == Service_CustomerProcess::getOwner( $param['customerCode'] ) ) $param['postcode']='';

        //计算重量
        $products = array();
        if( !isset( $this->_parameterArr['shippingFeeInfo']['productInfo'][0] ) ) {
            $products = array( $this->_parameterArr['shippingFeeInfo']['productInfo'] );
        } else {
            $products = $this->_parameterArr['shippingFeeInfo']['productInfo'];
        }

        $batteryType = array(
            1 => Ec_Lang::getInstance()->translate( 'equippedBattery', 'en_US' ),
            2 => Ec_Lang::getInstance()->translate( 'builtInBattery', 'en_US' ),
            3 => Ec_Lang::getInstance()->translate( 'buttonCell', 'en_US' ),
            4 => Ec_Lang::getInstance()->translate( 'LMPBattery', 'en_US' ),
            5 => Ec_Lang::getInstance()->translate( 'ionBattery', 'en_US' ),
            6 => Ec_Lang::getInstance()->translate( 'othersBattery', 'en_US' )
        );
        $weight = $volWeight = 0;
        foreach( $products as $value ) {
            $product = Service_Product::getByCondition( array( 'product_sku' => $value['productSku'], 'customer_code' => $this->_customerId ) );
            if( empty( $product ) ) {
                $this->_error[] = '12|SKU['.$value['productSku'].']'.Ec_Lang::getInstance()->translate( 'doesNotExist_l', 'en_US' );
                //只有内置电池和不带电池的才能发货
            } else if( $hasShipMethod && $shipMethod['sm_code'] == 'HKDHL' && $product[0]['with_battery'] == 1 && $product[0]['battery_type'] != 2 ) {
                $this->_error[] = '10|SKU['.$value['productSku'].']'.Ec_Lang::getInstance()->translate( 'batteryTypeIs', 'en_US' ).' '.$batteryType[$product[0]['battery_type']];
            } else {
                $weight += $product[0]['product_weight'] * $value['quantity'];
            }
            if( $shipMethod['sm_is_volume'] == 1 && $shipMethod['sm_vol_rate'] > 0 ) {
                $volWeight += ( $product[0]['product_length'] * $product[0]['product_width'] * $product[0]['product_height'] ) / $shipMethod['sm_vol_rate'];
            }
        }
        $volWeight = sprintf("%0.4f",$volWeight);
        $param['weight'] = $weight > $volWeight ? $weight : $volWeight;
        return $param;
    }

    private function checkParam() {

        if( !isset( $this->_parameterArr['shippingFeeInfo']['warehouseCode'] )
            || is_null( $this->_parameterArr['shippingFeeInfo']['warehouseCode'] )
            || $this->_parameterArr['shippingFeeInfo']['warehouseCode'] === '') {

            $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'warehouseIsRequired', 'en_US' );
        }

        $hasShipMethod = true;
        if( !isset( $this->_parameterArr['shippingFeeInfo']['smCode'] )
            || is_null( $this->_parameterArr['shippingFeeInfo']['smCode'] )
            || $this->_parameterArr['shippingFeeInfo']['smCode'] === '' ) {

            $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'transportCodeIsRequired', 'en_US' );
            $hasShipMethod = false;

        } else if( $this->_parameterArr['shippingFeeInfo']['smCode'] == 'DGF-CARGO'
            && ( !isset( $this->_parameterArr['shippingFeeInfo']['destination'] )
                || is_null( $this->_parameterArr['shippingFeeInfo']['destination'] )
                || $this->_parameterArr['shippingFeeInfo']['destination'] === '' ) ) {

            $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'airCodeIsRequired', 'en_US' );
        }

        if( !isset( $this->_parameterArr['shippingFeeInfo']['countryCode'] )
            || is_null( $this->_parameterArr['shippingFeeInfo']['countryCode'] )
            || $this->_parameterArr['shippingFeeInfo']['countryCode'] === '') {

            $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'countryIsRequired', 'en_US' );

        } else {

            $country = Service_Country::getByField( $this->_parameterArr['shippingFeeInfo']['countryCode'], 'country_code' );
            //美国HKDHL必填
            if( $country ) {
                if( $country['country_id'] == 253
                    && $hasShipMethod
                    && $this->_parameterArr['shippingFeeInfo']['smCode'] == 'HKDHL'
                    && ( !isset( $this->_parameterArr['shippingFeeInfo']['cityName'] )
                        || is_null( $this->_parameterArr['shippingFeeInfo']['cityName'] )
                        || $this->_parameterArr['shippingFeeInfo']['cityName'] === '' ) ) {

                    $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'cityIsRequired', 'en_US' );
                }

                $this->_parameterArr['countryId'] = $country['country_id'];
                $this->_parameterArr['countryCode'] = $country['country_code'];
            }
        }

        //计算重量
        if( !isset( $this->_parameterArr['shippingFeeInfo']['productInfo'] ) || empty( $this->_parameterArr['shippingFeeInfo']['productInfo'] ) ) {
            $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'skuIsRequired', 'en_US' );

        } else if( !is_array( $this->_parameterArr['shippingFeeInfo']['productInfo'] ) ) {
            $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'skuDataFormatWrong', 'en_US' );

        } else {
            $products = array();
            if( !isset( $this->_parameterArr['shippingFeeInfo']['productInfo'][0] ) ) {
                $products = array( $this->_parameterArr['shippingFeeInfo']['productInfo'] );
            } else {
                $products = $this->_parameterArr['shippingFeeInfo']['productInfo'];
            }
            foreach( $products as $value ) {
                if( !isset( $value['productSku'] ) || !isset( $value['quantity'] ) ) {
                    $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'skuDataFormatWrong', 'en_US' );
                    break;
                }
                $hasSKU = false;
                if( $value['productSku'] === '' || is_null( $value['productSku'] ) ) {
                    $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'skuIsEmpty', 'en_US' );
                } else {
                    $hasSKU = true;
                }
                if( !preg_match('/^[1-9]\d*$/',$value['quantity'] ) ) {
                    if( $hasSKU ) {
                        $this->_error[] = '11|['.$value['productSku'].']'.Ec_Lang::getInstance()->translate( 'skuQtyWrong', 'en_US' );
                    } else {
                        $this->_error[] = '11|'.Ec_Lang::getInstance()->translate( 'skuQtyWrong', 'en_US' );;
                    }
                }
            }
        }
    }

    public function debug($data) {
        $path = APPLICATION_PATH.'/../data/log/888.txt';
        file_put_contents($path, var_export($data,true)."\n", FILE_APPEND);
    }
}