<?php
class Common_CalculateShipping
{
    protected $_paramsArray = array(); //参数
    protected $_dataArray = array(); //自定义
    protected $_errorArray = array(); //错误信息
    protected $zccqShipType = array(
        'ZCCQ',
    );
    protected $iszccq = false;
    public function construct($params = array())
    {
        $this->setParams($params);
    }

    /**
     * @设置参数
     */
    public function setParams($params = array())
    {
        $keys = array(
            'customerCode' => '',
            'warehouseId' =>'',
            'countryId' => 0,
            'smId' => 0,
            'smCode' => '',
            'weight' => 0,
            'length' => 0,
            'width' => 0,
            'height' => 0,
            'provinceId' => 0,
            'cityId' => 0,
            'zip' => null,
            //  'warehouseName' => '',
            //  'countryCode' => '',
//            'smClassCode' => null, //运输方式分类的code
            'smFeeType' => null, //费用类型：单票,总单
            'smCalcType' => null, //计费类型：区间,首续重
            'realWeight'=> 0,
            'order_code'=>'',
            'postcode'=>'',
            'aircode'=>'',//空运计费的，机场三字码
        );
        if (is_array($params)) {
            foreach ($keys as $key => $val) {
                if (isset($params[$key])) {
                    $keys[$key] = $params[$key];
                }
            }
        }
        unset($params);
        $this->_paramsArray = $keys;
    }

    /**
     * @获取物流费用
     * @return array
     */
    public function getRate()
    {
        $result = array('state' => 0, 'error' => array(), 'data' => array(),'sm_channel'=>'0');
        $this->setShippingMethod();
        //选择自有渠道的订单，不需要进行物流费用的冻结、扣款 order表change_order是0 shipping_method的sm_channel是1
        if($this->_dataArray['smArr']['sm_channel']=='1'){
            //不需要物流费的直接返回物流费为0
            $directoryArray =  array(
                'weight' => '0',
                'cost' => '0',
                'price' => '0',
                'totalCost'=>'0',
                'currency_code' => 'RMB',
                'sm_channel'=>'1' //自有渠道
            );
            $result = array('state' => 1, 'data' => array('sm' => $this->_dataArray['smArr'], 'cost' => $directoryArray));
            return $result;
        }
        $this->setCountry();
        $this->setRealWeight();
        $this->validator();
        if (!empty($this->_errorArray)) {
            $result['error'] = $this->getError();
            return $result;
        }
        $this->setArea();
        $this->getCostRate();
        if (!empty($this->_errorArray)) {
            $result['error'] = $this->getError();
            return $result;
        }
        $this->setDiscount();
        $this->setCustomerDiscount();
        $this->costAccounting();
        $result = array('state' => 1, 'data' => array('sm' => $this->_dataArray['smArr'], 'cost' => $this->_dataArray['costArr']));
        return $result;
    }

    /**
     *@首续重计费模式+区间重量计费 所有可用货运方式
     *@根据 仓库ID,国家ID,省份ID,城市ID 计费类型(默认全部) 获取可用的货运方式;
     * @return array('state'=>0,'message'=>string,'data'=array())
     */
    public function getArrivedSM()
    {
        $return = array('state' => 0, 'message' => 'No data', 'data' => array());
        $condition = array(
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
            'country_id_arr' => array(0, $this->_paramsArray['countryId']),
            'province_id_arr' => array(0, $this->_paramsArray['provinceId']),
            'city_id_arr' => array(0, $this->_paramsArray['cityId']),
        );
        $smCondition = array(
            'sm_status' => 1,
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
            'sm_calc_type' => $this->_paramsArray['smCalcType'],
            'sm_fee_type' => $this->_paramsArray['smFeeType'],
        );
        $shippingMethodRows = Service_ShippingMethod::getByCondition($smCondition, '*');
        if (empty($shippingMethodRows)) {
            return $return;
        }
        $smCodeArr = array();
        foreach ($shippingMethodRows as $sm) {
            $condition['smcm_type'] = $sm['sm_calc_type'];
            $condition['smcm_calc_type'] = $sm['sm_fee_type'];
            $mapRows = Service_SmCountryMap::getByInCondition($condition, 'area', 0, 0, array('warehouse_id desc', 'country_id desc', 'province_id desc', 'city_id desc'));
            if (!empty($mapRows)) {
                $smCodeArr[] = array(
                    'sm_id' => $sm['sm_id'],
                    'sm_code' => $sm['sm_code'],
                    'sm_calc_type' => $sm['sm_calc_type'],
                    'sm_fee_type' => $sm['sm_fee_type'],
                    'sm_limit_weight' => $sm['sm_limit_weight'],
                );
            }
        }
        if (!empty($smCodeArr)) {
            $return = array('state' => 1, 'message' => 'Success', 'data' => $smCodeArr);
        }
        return $return;
    }

    /**
     * @desc 获取所有可到达的运输方式及运费
     * @params 根据仓库ID,国家ID,计费类型,重量,长,宽,高,客户Code
     * @return array('state'=>0,'message'=>string,'data'=array())
     */
    public function getAllShippingMethodCost()
    {
        $return = array('state' => 0, 'message' => 'No data', 'data' => array());
        $smCondition = array(
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
            'sm_status' => 1,
            'sm_calc_type' => $this->_paramsArray['smCalcType'],
            'sm_fee_type' => $this->_paramsArray['smFeeType'],
        );
        $shippingMethodRows = Service_ShippingMethod::getByCondition($smCondition, '*');
        if (empty($shippingMethodRows)) {
            return $return;
        }
        $costArr = array();
        foreach ($shippingMethodRows as $sm) {
            $this->_paramsArray['smCode'] = $sm['sm_code'];
            $result = $this->getRate();
            $this->_errorArray = array();
            if (isset($result['state']) && $result['state'] == '1') {
                $costArr[] = $result['data'];
            }
        }
        if (!empty($costArr)) {
            $return = array('state' => 1, 'message' => 'Success', 'data' => $costArr);
        }
        return $return;
    }

    private function getError()
    {
        $error = array(
            '1' => 'Country does not exist',
            '2' => 'Shipping method does not exist',
            '3' => 'Incorrect Weight',
            '4' => 'The shipping method is not available for this country',
            '5' => 'No Ship Price',
            '6' => 'Please choose shipping method first',
            '7' => 'Over Weight,Maximum weight:'.$this->_dataArray['smArr']['sm_limit_weight'],
            '8' => 'The shipping method is not available for this warehouse',
            '9' => 'Warehouse method does not exist',
            '11'=> Ec_Lang::getInstance()->getTranslate('aircode_not_exist'),
            '12'=> Ec_Lang::getInstance()->getTranslate('shipping_aircode_not_exist'),
        );
        $errorArr = array();
        foreach ($this->_errorArray as $code) {
            if (isset($error[$code])) {
                $errorArr[] = $error[$code];
            }
        }
        return $errorArr;
    }

    private function setShippingMethod()
    {
        if ($this->_paramsArray['smCode'] != '') {
            /* $smRow = Service_ShippingMethod::getByField($this->_paramsArray['smCode'], 'sm_code');
            if ($smRow['sm_status'] == '1') {
                $this->_dataArray['smArr'] = $smRow;
            } */
            $conditionSm = array(
            		'sm_code'=>$this->_paramsArray['smCode'],
            		'warehouse_id_arr'=>array('0',$this->_paramsArray['warehouseId'])
            );
            $smRowAll = Service_ShippingMethod::getByCondition($conditionSm,'*',1,1,'warehouse_id desc');
            $smRow = $smRowAll[0];
            if ($smRow['sm_status'] == '1') {
            	$this->_dataArray['smArr'] = $smRow;
            }
            return true;
        }
        if ($this->_paramsArray['smId'] != '' && $this->_paramsArray['smId'] != '0') {
            $smRow = Service_ShippingMethod::getByField($this->_paramsArray['smId'], 'sm_id');
            if ($smRow['sm_status'] == '1') {
                $this->_dataArray['smArr'] = $smRow;
            }
            return true;
        }
    }

    private function setCountry()
    {
        $this->_dataArray['countryArr'] = Service_Country::getByField($this->_paramsArray['countryId'], 'country_id');
    }

    private function validator()
    {
        if(empty($this->_paramsArray['warehouseId'])){
            $this->_errorArray[] = '9'; //仓库不能为空
        }
        if (empty($this->_dataArray['smArr']) || !isset($this->_dataArray['smArr'])) {
            $this->_errorArray[] = '1'; //货运方式不存在.
        } elseif (!in_array($this->_dataArray['smArr']['warehouse_id'], array(0, $this->_paramsArray['warehouseId']))) {
            $this->_errorArray[] = '8'; //货运方式不支持仓库
        }
        if (empty($this->_dataArray['countryArr']) || !isset($this->_dataArray['countryArr'])) {
            $this->_errorArray[] = '2'; //国家不存在.
        }
        if (empty($this->_paramsArray['weight'])) {
            $this->_errorArray[] = '3'; //重量不能为空
        } elseif (isset($this->_dataArray['realWeight']) && $this->_dataArray['realWeight'] > $this->_dataArray['smArr']['sm_limit_weight']) {
            $this->_errorArray[] = '7'; //超重
        }
    }

    /**
     * @desc 计费重量
     * @return bool
     */
    private function setRealWeight()
    {
        if (!isset($this->_dataArray['smArr'])) {
            return false;
        }
        $this->_dataArray['realWeight'] = $this->_paramsArray['realWeight']>$this->_paramsArray['weight']? $this->_paramsArray['realWeight']:$this->_paramsArray['weight'];
        /*if ($this->_dataArray['smArr']['sm_is_volume'] == '1' && $this->_dataArray['smArr']['sm_vol_rate'] > 0 ) {
        	if(isset($this->_paramsArray['length']) && $this->_paramsArray['length']>0 && isset($this->_paramsArray['width']) && $this->_paramsArray['width']>0 && isset($this->_paramsArray['height']) && $this->_paramsArray['height']>0 ){
        		$vol = $this->_paramsArray['length'] * $this->_paramsArray['width'] * $this->_paramsArray['height'];
        		$volWeight = sprintf("%.2f", $vol / $this->_dataArray['smArr']['sm_vol_rate']);
        		if ($volWeight > $this->_paramsArray['weight'] && $vol > $this->_dataArray['smArr']['sm_limit_volume']) {
        			$this->_dataArray['realWeight'] = $volWeight;
        		}
        	}
        }*/
    }

    /**
     * @desc 设置分区代码
     * @ set $this->_dataArray['areaArr']
     */
    private function setArea()
    {
        $this->_dataArray['areaArr'] = array();
        $condition = array(
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
            'country_id_arr' => array(0, $this->_paramsArray['countryId']),
            'province_id_arr' => array(0, $this->_paramsArray['provinceId']),
            'city_id_arr' => array(0, $this->_paramsArray['cityId']),
            'sm_id' => $this->_dataArray['smArr']['sm_id'],
            'regex_post_code'=>$this->_paramsArray['postcode'],
        );
        if(empty($condition['regex_post_code'])&&!empty($this->_paramsArray['order_code'])){
            $addressCondition=array(
                'order_code'=>$this->_paramsArray['order_code'],
                'oab_type'=>'0'
            );
            $receiptAddressPostCode=  Service_OrderAddressBook::getByWhere($addressCondition,'oab_postcode');
            if(!empty($receiptAddressPostCode)){
                $condition['regex_post_code']=$receiptAddressPostCode['oab_postcode'];
            }
        }
        $condition['smcm_type'] = $this->_dataArray['smArr']['sm_calc_type'];
        $condition['smcm_calc_type'] = $this->_dataArray['smArr']['sm_fee_type'];

        if($this->_dataArray['smArr']['sm_code']=='DGF-CARGO'){
            if( $this->_paramsArray['aircode'] === '' || is_null( $this->_paramsArray['aircode'] ) ) {
                return false;
            }
            //空运的只查找机场,不用查国家了
            $condition['aircode'] = $this->_paramsArray['aircode'];
            //unset($condition['country_id_arr']);
        }

        $mapRows = Service_SmCountryMap::getByInCondition($condition, 'area', 0, 0, array('warehouse_id desc', 'country_id desc', 'province_id desc', 'city_id desc'));
        if (empty($mapRows)) {
            $condition['regex_post_code']='';
             $mapRows = Service_SmCountryMap::getByInCondition($condition, 'area', 0, 0, array('warehouse_id desc', 'country_id desc', 'province_id desc', 'city_id desc'));
             if(empty($mapRows)){
                return false;
             }
        }
        foreach ($mapRows as $val) {
            $areaArr[] = $val['area'];
        }
        $this->_dataArray['areaArr'] = $areaArr;
        return true;
    }

    /**
     * @desc 获取相对应该的基本费用
     */
    private function getCostRate()
    {
        $areaArr = isset($this->_dataArray['areaArr']) ? $this->_dataArray['areaArr'] : array();
        if (empty($areaArr)) {
            $this->_errorArray[] = '4'; //货运方式国家不存在对应的区域
            return false;
        }
        $customerCode = self::hasCustomerPrice();
        //区间价格
        if ($this->_dataArray['smArr']['sm_calc_type'] == '0') {
            if( $customerCode ) {
                $priceRow = $this->customerPriceInterval( $customerCode, $areaArr );
            } else {
                $priceRow = $this->interval($areaArr);
            }
        } else {
            //首续重
            if( $customerCode ) {
                $priceRow = $this->customerFirstWeight( $customerCode, $areaArr );
            } else {
                $priceRow = $this->firstWeight($areaArr);
            }

        }
        if (!is_array($priceRow)) {
            return false;
        }
        $this->_dataArray['costArr'] = $priceRow;
    }
      /**
     * @desc 获取计费重
     */
    public  function getFeeWeight()
    {
        
        $result = array('state' => 0, 'error' => array(), 'data' => array(),'sm_channel'=>'0');
        $this->setShippingMethod();
        //选择自有渠道的订单，不需要进行物流费用的冻结、扣款 order表change_order是0 shipping_method的sm_channel是1
        if($this->_dataArray['smArr']['sm_channel']=='1'){
            //不需要物流费的直接返回物流费为0
            $directoryArray =  array(
                'weight' => '0',
                'cost' => '0',
                'price' => '0',
                'totalCost'=>'0',
                'currency_code' => 'RMB',
                'sm_channel'=>'1' //自有渠道
            );
            $result = array('state' => 1, 'data' => array('sm' => $this->_dataArray['smArr'], 'cost' => $directoryArray));
            return $result;
        }
        $this->setCountry();
        $this->setRealWeight();
        $this->validator();
        if (!empty($this->_errorArray)) {
            $result['error'] = $this->getError();
            return $result;
        }
        $this->setArea();
        $areaArr = isset($this->_dataArray['areaArr']) ? $this->_dataArray['areaArr'] : array();
        if (empty($areaArr)) {
            $this->_errorArray[] = '4'; //货运方式国家不存在对应的区域
            return false;
        }
        $hasCustomerPrice = self::hasCustomerPrice();
        //区间价格
        if ($this->_dataArray['smArr']['sm_calc_type'] == '0') {
            if( $hasCustomerPrice ) {
                $priceRow = $this->customerPriceInterval($areaArr);
            } else {
                $priceRow = $this->interval($areaArr);
            }
		//首续重
        } else {
            if( $hasCustomerPrice ) {
                $priceRow = $this->customerFirstWeight($areaArr);
            } else {
                $priceRow = $this->firstWeight($areaArr);
            }
        }
        if (!is_array($priceRow)) {
            return false;
        }else{
            $result['state']=1;
            $result['data']=array(
                'fee_weight'=>$priceRow['fee_weight'],
            );
        }
       
    }
    /**
     * @desc 区间
     * @param array $areaArr
     * @return array|bool
     */
    private function interval($areaArr = array())
    {
        $condition = array(
	            'sm_id' => $this->_dataArray['smArr']['sm_id'],
	            'area_arr' => $areaArr,
	            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
	            'sp_fee_type' => $this->_dataArray['smArr']['sm_fee_type'],
	            'sp_weight_gt' => $this->_dataArray['realWeight'],
        );
        $spObj = new Table_ShipPrice();
        $smPriceRows = $spObj->getByInCondition($condition, '*', array('sp_weight', 'date_start desc', 'sp_id desc', 'warehouse_id desc', 'sp_price'));
    	//获取有效报价，取第一条，其余的报价有效截止日期设置成当前日期
        if(is_array($smPriceRows) && !empty($smPriceRows)){
        	$date_end = date('Y-m-d', strtotime("-1 days"));
        	foreach ($smPriceRows as $smKey=>$smVal){
        		if($smKey == 0){
        			//取第一条
        			$smPriceRow = $smVal;
        			continue;
        		}
                /*
        		//大于部分不处理
        		if($smVal['sp_weight'] > $smPriceRow['sp_weight']){
        			continue;
        		}else{
        			if(!empty($smPriceRow) && is_array($smPriceRow) && $smPriceRow['date_start'] != '0000-00-00'){
        				$date_end = date('Y-m-d', strtotime($smPriceRow['date_start']) - 86400);
        			}
        			//将其他的报价截止日期设置成前一天
        			$spObj->update(array('date_end'=>$date_end), $smVal['sp_id']);
        		}
                */
        	}
        }
		if (empty($smPriceRow)) {
            $this->_errorArray[] = '5'; //没有找到费用
            return false;
        }
		$currencyArr=Service_Currency::getByField($smPriceRow['currency_code'],'currency_code',array('currency_rate'));
        $smRow = Service_ShippingMethod::getByField($smPriceRow['sm_code'],"sm_code","*");
        $one_ticket_fee = 0;
        $one_ticket_cbcost = 0;
        if(in_array($this->_dataArray['smArr']['sm_class_code'], array("CPS","CRP","CRE"))){
            $one_ticket_fee = $smPriceRow['sp_ticket_cost'];
        }
        if(in_array($this->_dataArray['smArr']['sm_class_code'], array("CPS","CRP","CRE"))){
            $one_ticket_cbcost = $smPriceRow['one_ticket_cbcost'];
        }

        // 判断是否存在成本币种，否则成本币种与费用币种一致（程序兼容性）
        if ('' === trim($smPriceRow['cost_currency_code'])) {
          $smPriceRow['cost_currency_code'] = $smPriceRow['currency_code'];
        }
        $fee_weight = $this->_dataArray['realWeight'];
        if($smPriceRow['sp_weight']>$fee_weight){
            $fee_weight=$smPriceRow['sp_weight'];
        }
        $priceRow = array(
            'weight' => $smPriceRow['sp_weight'],
            'fee_weight'=> $fee_weight,
            'cost' => sprintf('%.3f', $smPriceRow['sp_cost']),
            'price' => sprintf('%.3f', $smPriceRow['sp_price']),
            'cost_currency_code' => $smPriceRow['cost_currency_code'], // 成本币种
            'currency_code' => $smPriceRow['currency_code'],
            'currency_rate' => $currencyArr['currency_rate'],
            'type' => $smPriceRow['sp_fee_type'],
            'sm_id' => $smPriceRow['sm_id'],
            'one_ticket_fee'=>$one_ticket_fee,
            'one_ticket_cbcost'=>$one_ticket_cbcost,
            'map_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $smPriceRow['sp_cost']), // 成本费用转变为与费用一致的币种
            'map_one_ticket_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $one_ticket_cbcost), // 成本单票费用转变为与费用一致的币种
            'price_batch_number' => $smPriceRow['price_batch_number'], // 价格编号
        );
        return $priceRow;
    }

    /**
     * @desc 客户区间
     * @param array $areaArr
     * @return array|bool
     */
    private function customerPriceInterval( $customerCode, $areaArr = array() )
    {
        $condition = array(
            'sm_id' => $this->_dataArray['smArr']['sm_id'],
            'area_arr' => $areaArr,
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
            'scp_fee_type' => $this->_dataArray['smArr']['sm_fee_type'],
            'scp_weight_gt' => $this->_dataArray['realWeight'],
            'customer_code'=> $customerCode,
        );
        $order = array('scp_weight', 'date_start desc', 'scp_id desc', 'warehouse_id desc', 'scp_price');
        $smPriceRows = Service_ShipCustomerPrice::getByCondition( $condition,'*', 1, 1, $order );
        if (empty($smPriceRows)) {
            $this->_errorArray[] = '5'; //没有找到费用
            return false;
        }

        $smPriceRow = $smPriceRows[0];

        $currencyArr=Service_Currency::getByField($smPriceRow['currency_code'],'currency_code',array('currency_rate'));
        $smRow = Service_ShippingMethod::getByField($smPriceRow['sm_code'],"sm_code","*");
        $one_ticket_fee = 0;
        $one_ticket_cbcost = 0;
        if(in_array($this->_dataArray['smArr']['sm_class_code'], array("CPS","CRP","CRE"))){
            $one_ticket_fee = $smPriceRow['scp_ticket_cost'];
        }
        if(in_array($this->_dataArray['smArr']['sm_class_code'], array("CPS","CRP","CRE"))){
            $one_ticket_cbcost = $smPriceRow['one_ticket_cbcost'];
        }

        // 判断是否存在成本币种，否则成本币种与费用币种一致（程序兼容性）
        if ('' === trim($smPriceRow['cost_currency_code'])) {
            $smPriceRow['cost_currency_code'] = $smPriceRow['currency_code'];
        }
        $fee_weight = $this->_dataArray['realWeight'];
        if($smPriceRow['scp_weight']>$fee_weight){
            $fee_weight=$smPriceRow['scp_weight'];
        }
        $priceRow = array(
            'weight' => $smPriceRow['scp_weight'],
            'fee_weight'=> $fee_weight,
            'cost' => sprintf('%.3f', $smPriceRow['scp_cost']),
            'price' => sprintf('%.3f', $smPriceRow['scp_price']),
            'cost_currency_code' => $smPriceRow['cost_currency_code'], // 成本币种
            'currency_code' => $smPriceRow['currency_code'],
            'currency_rate' => $currencyArr['currency_rate'],
            'type' => $smPriceRow['scp_fee_type'],
            'sm_id' => $smPriceRow['sm_id'],
            'one_ticket_fee'=>$one_ticket_fee,
            'one_ticket_cbcost'=>$one_ticket_cbcost,
            'map_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $smPriceRow['scp_cost']), // 成本费用转变为与费用一致的币种
            'map_one_ticket_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $one_ticket_cbcost), // 成本单票费用转变为与费用一致的币种
            'price_batch_number' => $smPriceRow['price_batch_number'], // 价格编号
        );
        return $priceRow;
    }


    /**
     * @desc 首续重
     * @param array $areaArr
     * @return array|bool
     */
    private function firstWeight($areaArr = array())
    {
        $condition = array(
            'sm_id' => $this->_dataArray['smArr']['sm_id'],
            'area_arr' => $areaArr,
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
            'swp_fee_type' => $this->_dataArray['smArr']['sm_fee_type']
        );
        $spObj = new Table_ShipWeightPrice();
        $smPriceRows = $spObj->getByInCondition($condition, '*', array('date_start desc', 'swp_id desc','warehouse_id desc'));
        $date_end = date('Y-m-d', strtotime("-1 days"));
        //获取有效报价，取第一条，其余的报价有效截止日期设置成当前日期
        if(is_array($smPriceRows) && !empty($smPriceRows)){
        	foreach ($smPriceRows as $smKey=>$smVal){
        		if($smKey == 0){
        			//取第一条
        			$smPriceRow = $smVal;
        			continue;
        		}
                /*
        		if(!empty($smPriceRow) && is_array($smPriceRow) && $smPriceRow['date_start'] != '0000-00-00'){
        			$date_end = date('Y-m-d', strtotime($smPriceRow['date_start']) - 86400);
        		}
        		//将其他的报价截止日期设置成前一天
        		$spObj->update(array('date_end'=>$date_end), $smVal['swp_id']);
                */
        	}
        }
        
        if (empty($smPriceRow)) {
            $this->_errorArray[] = '5'; //没有找到费用
            return false;
        }
        $currencyArr=Service_Currency::getByField($smPriceRow['currency_code'],'currency_code',array('currency_rate'));
        //费用计算
        if ($smPriceRow["swp_weight"] - $this->_dataArray['realWeight'] > 0) {
            $cost = $smPriceRow["swp_cost"];
            $price = $smPriceRow["swp_price"];
        } else {
            $cost = ($this->_dataArray['realWeight'] - $smPriceRow["swp_weight"]) / $smPriceRow["swp_exces_weight"];
            $cost = ceil($cost) * $smPriceRow["swp_exces_cost"] + $smPriceRow["swp_cost"];
            $price = ($this->_dataArray['realWeight'] - $smPriceRow["swp_weight"]) / $smPriceRow["swp_exces_weight"];
            $price = ceil($price) * $smPriceRow["swp_exces_price"] + $smPriceRow["swp_price"];
        }
        $one_ticket_cbcost = 0;
        if(in_array($this->_dataArray['smArr']['sm_class_code'], array("CPS","CRP","CRE"))){
            $one_ticket_cbcost = $smPriceRow['one_ticket_cbcost'];
        }

        // 判断是否存在成本币种，否则成本币种与费用币种一致（程序兼容性）
        if ('' === trim($smPriceRow['cost_currency_code'])) {
          $smPriceRow['cost_currency_code'] = $smPriceRow['currency_code'];
        }
        $fee_weight = $this->_dataArray['realWeight'];
        $costNumber = ($this->_dataArray['realWeight'] - $smPriceRow["swp_weight"]) / $smPriceRow["swp_exces_weight"];
        $fee_weight=$smPriceRow['swp_weight']+ceil($costNumber)*$smPriceRow["swp_exces_weight"];
        $priceRow = array(
            'weight' => $smPriceRow['swp_weight'],
            'addedWeight' => $smPriceRow['swp_exces_weight'],
            'fee_weight' => $fee_weight,
            'cost' => sprintf('%.3f', $cost),
            'price' => sprintf('%.3f', $price),
            'cost_currency_code' => $smPriceRow['cost_currency_code'], // 成本币种
            'currency_code' => $smPriceRow['currency_code'],
            'currency_rate' => $currencyArr['currency_rate'],
            'type' => $smPriceRow['swp_fee_type'],
            'sm_id' => $smPriceRow['sm_id'],
            'one_ticket_fee'=>$smPriceRow['one_ticket_fee'],
            'one_ticket_cbcost'=>$one_ticket_cbcost,
            'map_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $cost), // 成本费用转变为与费用一致的币种
            'map_one_ticket_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $one_ticket_cbcost), // 成本单票费用转变为与费用一致的币种
            'price_batch_number' => $smPriceRow['price_batch_number'], // 价格编号
        );
        return $priceRow;
    }

    /**
     * @desc 客户首续重
     * @param array $areaArr
     * @return array|bool
     */
    private function customerFirstWeight( $customerCode, $areaArr = array() )
    {
        $condition = array(
            'sm_id' => $this->_dataArray['smArr']['sm_id'],
            'area_arr' => $areaArr,
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId']),
            'scwp_fee_type' => $this->_dataArray['smArr']['sm_fee_type'],
            'customer_code'=> $customerCode,
        );
        $smPriceRows = Service_ShipCustomerWeightPrice::getByCondition( $condition, '*', 1, 1, array('date_start desc', 'scwp_id desc','warehouse_id desc') );
        if (empty($smPriceRows)) {
            $this->_errorArray[] = '5'; //没有找到费用
            return false;
        }
        $smPriceRow = $smPriceRows[0];

        $currencyArr=Service_Currency::getByField($smPriceRow['currency_code'],'currency_code',array('currency_rate'));
        //费用计算
        if ($smPriceRow["swp_weight"] - $this->_dataArray['realWeight'] > 0) {
            $cost = $smPriceRow["scwp_cost"];
            $price = $smPriceRow["scwp_price"];
        } else {
            $cost = ($this->_dataArray['realWeight'] - $smPriceRow["scwp_weight"]) / $smPriceRow["scwp_exces_weight"];
            $cost = ceil($cost) * $smPriceRow["scwp_exces_cost"] + $smPriceRow["scwp_cost"];
            $price = ($this->_dataArray['realWeight'] - $smPriceRow["scwp_weight"]) / $smPriceRow["scwp_exces_weight"];
            $price = ceil($price) * $smPriceRow["scwp_exces_price"] + $smPriceRow["scwp_price"];
        }
        $one_ticket_cbcost = 0;
        if(in_array($this->_dataArray['smArr']['sm_class_code'], array("CPS","CRP","CRE"))){
            $one_ticket_cbcost = $smPriceRow['one_ticket_cbcost'];
        }

        // 判断是否存在成本币种，否则成本币种与费用币种一致（程序兼容性）
        if ('' === trim($smPriceRow['cost_currency_code'])) {
            $smPriceRow['cost_currency_code'] = $smPriceRow['currency_code'];
        }
        $fee_weight = $this->_dataArray['realWeight'];
        $costNumber = ($this->_dataArray['realWeight'] - $smPriceRow["scwp_weight"]) / $smPriceRow["scwp_exces_weight"];
        $fee_weight=$smPriceRow['scwp_weight']+ceil($costNumber)*$smPriceRow["scwp_exces_weight"];
        $priceRow = array(
            'weight' => $smPriceRow['scwp_weight'],
            'addedWeight' => $smPriceRow['scwp_exces_weight'],
            'fee_weight' => $fee_weight,
            'cost' => sprintf('%.3f', $cost),
            'price' => sprintf('%.3f', $price),
            'cost_currency_code' => $smPriceRow['cost_currency_code'], // 成本币种
            'currency_code' => $smPriceRow['currency_code'],
            'currency_rate' => $currencyArr['currency_rate'],
            'type' => $smPriceRow['scwp_fee_type'],
            'sm_id' => $smPriceRow['sm_id'],
            'one_ticket_fee'=>$smPriceRow['one_ticket_fee'],
            'one_ticket_cbcost'=>$one_ticket_cbcost,
            'map_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $cost), // 成本费用转变为与费用一致的币种
            'map_one_ticket_cost' => Service_Currency::converByCode($smPriceRow['cost_currency_code'], $smPriceRow['currency_code'], $one_ticket_cbcost), // 成本单票费用转变为与费用一致的币种
            'price_batch_number' => $smPriceRow['price_batch_number'], // 价格编号
        );
        return $priceRow;
    }

    /**
     * @desc 计算运输方式折扣及其它费用
     */
    private function setDiscount()
    {
        $this->_dataArray['costArr']['addCost'] = sprintf('%.3f', $this->_dataArray['smArr']['sm_addons']);//附加费
        $this->_dataArray['costArr']['pCost'] = sprintf('%.3f', $this->_dataArray['smArr']['sm_mp_fee']);//运输方式处理费
        $this->_dataArray['costArr']['regCost'] = sprintf('%.3f', $this->_dataArray['smArr']['sm_reg_fee']);//运输方式挂号费

        /* 计算燃油附加费 */
        $shippingMethod = Service_ShippingMethod::getByField($this->_dataArray['smArr']['sm_id'],"sm_id","*");
        if('CRE' == $shippingMethod['sm_class_code']){
           $otherfee = Service_OtherFee::getByField('CHAOCHANG', 'fee_code');
           
           $chaochangfee=0;
           $shipOrderDetail=Service_ShipOrderDetail::getByField($this->_paramsArray['order_code'],'order_code');
                    if ((int)$shipOrderDetail['sod_length']>120||(int)$shipOrderDetail['sod_width']>120||(int)$shipOrderDetail['sod_height']>120||(int)$shipOrderDetail['sod_weight']>70){
                        $feeValue = Service_Currency::converByCode($otherfee['fee_currency_code'], $this->_dataArray['costArr']['currency_code'], $otherfee['fee_value']);
                        $chaochangfee=$feeValue;   
                    }
            if ($this->_paramsArray['smCode']=='HKDHL') {
                 $baf = ($this->_dataArray['costArr']['price'] + $this->_dataArray['costArr']['addCost'] + $this->_dataArray['costArr']['pCost'] + $this->_dataArray['costArr']['regCost']+$chaochangfee) * $shippingMethod['sm_baf'];
            }else{
                $baf = ($this->_dataArray['costArr']['price'] + $this->_dataArray['costArr']['addCost'] + $this->_dataArray['costArr']['pCost'] + $this->_dataArray['costArr']['regCost']) * $shippingMethod['sm_baf'];
            }
         
          $baseBaf = $baf;
          $cost_baf = $this->_dataArray['costArr']['cost'] * $shippingMethod['sm_baf'];
          $map_cost_baf = Service_Currency::converByCode($this->_dataArray['costArr']['cost_currency_code'], $this->_dataArray['costArr']['currency_code'], $cost_baf);
        }
        else {
          $baf = '0.00';
          $cost_baf = '0.00';
          $map_cost_baf = '0.00';
          $baseBaf = '0.00';
        }

        $discount = $this->_dataArray['smArr']['sm_discount'];
        $discount = 1; //暂时不开放
        $baseCost = $this->_dataArray['costArr']['price'] * $discount;
        $oneTicketFee = isset($this->_dataArray['costArr']['one_ticket_fee'])?$this->_dataArray['costArr']['one_ticket_fee']:'0';
        $baseTicketFee = $oneTicketFee * $discount; // 单票费用也要打折

        //控制成本
        $cost_total = $this->_dataArray['costArr']['map_cost'] + $this->_dataArray['costArr']['map_one_ticket_cost'] + $map_cost_baf; // 成本费用
        $real_total = $baseCost + $baseTicketFee + $baf; // 实际费用
        if ($real_total < $cost_total) {
          $baseCost = $this->_dataArray['costArr']['map_cost'];
          $baseTicketFee = $this->_dataArray['costArr']['map_one_ticket_cost'];
          $baseBaf = $map_cost_baf;
        }
        //sm_addons 运输方式附加费
        //pCost

        //$oneTicketCbCost = $this->_dataArray['costArr']['one_ticket_cbcost'];
        $this->_dataArray['costArr']['baseCost'] = sprintf('%.3f', $baseCost);
        $this->_dataArray['costArr']['baseTicketFee'] = sprintf('%.3f', $baseTicketFee);
        $this->_dataArray['costArr']['baseBaf'] = sprintf('%.3f', $baseBaf); // 实际需要扣费的燃油费
        $this->_dataArray['costArr']['baf'] = sprintf('%.3f', $baf); // 燃油费
        $this->_dataArray['costArr']['cost_baf'] = sprintf('%.3f', $cost_baf); // 成本燃油费
        $this->_dataArray['costArr']['map_cost_baf'] = sprintf('%.3f', $map_cost_baf); // 成本燃油费转变为与费用一致的币种
        $this->_dataArray['costArr']['totalCost'] = sprintf('%.3f', $baseCost + $baseTicketFee + $baseBaf + $this->_dataArray['costArr']['addCost'] + $this->_dataArray['costArr']['pCost'] + $this->_dataArray['costArr']['regCost']);
    }

    /**
     * @desc 根据客户及运输方式获取折扣率
     * set $this->_dataArray['smArr']['customer_discount']
     */
    private function setCustomerDiscount()
    {
        $discount = 1; //默认无折扣
        $condition = array(
            'customer_code_arr' => array('*', $this->_paramsArray['customerCode']),
            'sm_code_arr' => array('*', $this->_dataArray['smArr']['sm_code']),
            'warehouse_id_arr' => array(0, $this->_paramsArray['warehouseId'])
        );
        $obj = new Table_SmCustomerMap();
        $customerMap = $obj->getByCondition($condition, '*', 5, 1, array('sm_code desc', 'customer_code desc', 'warehouse_id desc'));
        if (empty($customerMap)) {
            $this->_dataArray['smArr']['customer_discount'] = $discount;
            return false;
        }
        $smArr = array();
        foreach ($customerMap as $val) {
            if ($val['customer_code'] == $this->_paramsArray['customerCode'] && $val['warehouse_id'] == $this->_paramsArray['warehouseId'] && $this->_dataArray['smArr']['sm_code'] == $val['sm_code']) {
                $this->_dataArray['smArr']['customer_discount'] = $val['smc_discount'] > 0 ? $val['smc_discount'] : $discount;
                return true;
            }
            $smArr[$val['sm_code'] . '_' . $val['customer_code'] . '_' . $val['warehouse_id']] = $val['smc_discount'] > 0 ? $val['smc_discount'] : $discount;
        }
        if (isset($smArr[$this->_dataArray['smArr']['sm_code'] . '_' . $this->_paramsArray['customerCode'] . '_0'])) {
            $this->_dataArray['smArr']['customer_discount'] = $smArr[$this->_dataArray['smArr']['sm_code'] . '_' . $this->_paramsArray['customerCode'] . '_0'];
            return true;
        }
        if (isset($smArr[$this->_dataArray['smArr']['sm_code'] . '_*_' . $this->_paramsArray['warehouseId']])) {
            $this->_dataArray['smArr']['customer_discount'] = $smArr[$this->_dataArray['smArr']['sm_code'] . '_*_' . $this->_paramsArray['warehouseId']];
            return true;
        }
        if (isset($smArr[$this->_dataArray['smArr']['sm_code'] . '_*_0'])) {
            $this->_dataArray['smArr']['customer_discount'] = $smArr[$this->_dataArray['smArr']['sm_code'] . '_*_0'];
            return true;
        }
        if (isset($smArr['*_' . $this->_paramsArray['customerCode'] . '_' . $this->_paramsArray['warehouseId']])) {
            $this->_dataArray['smArr']['customer_discount'] = $smArr['*_' . $this->_paramsArray['customerCode'] . '_' . $this->_paramsArray['warehouseId']];
            return true;
        }
        $this->_dataArray['smArr']['customer_discount'] = $customerMap[0]['smc_discount'] > 0 ? $customerMap[0]['smc_discount'] : $discount;
        return true;
    }

    /**
     * @desc 成本核算
     */
    private function costAccounting()
    {
        $baseCost = $this->_dataArray['costArr']['baseCost'];
        $baseTicketFee = $this->_dataArray['costArr']['baseTicketFee'];
        if (isset($this->_dataArray['smArr']['customer_discount']) && $this->_dataArray['smArr']['customer_discount'] > 0) {
            $baseCost = $baseCost * $this->_dataArray['smArr']['customer_discount'];
            $baseTicketFee = $baseTicketFee * $this->_dataArray['smArr']['customer_discount'];
        }

        $baseBaf = $this->_dataArray['costArr']['baseBaf'];
        $cost_total = $this->_dataArray['costArr']['map_cost'] + $this->_dataArray['costArr']['map_one_ticket_cost'] + $this->_dataArray['costArr']['cost_baf']; // 成本费用
        $real_total = $baseCost + $baseTicketFee + $baseBaf; // 实际费用
        if ($real_total < $cost_total) {
          $baseCost = $this->_dataArray['costArr']['map_cost'];
          $baseTicketFee = $this->_dataArray['costArr']['map_one_ticket_cost'];
          $baseBaf = $this->_dataArray['costArr']['map_cost_baf'];
        }

        //$oneTicketFee = isset($this->_dataArray['costArr']['one_ticket_fee'])?sprintf('%.2f',$this->_dataArray['costArr']['one_ticket_fee']):'0';
        //$oneTicketCbCost = $this->_dataArray['costArr']['one_ticket_cbcost'];
        $baseCost = sprintf('%.3f', $baseCost);
        $baseTicketFee = sprintf('%.3f', $baseTicketFee);
        $this->_dataArray['costArr']['baseCost'] = $baseCost;
        $this->_dataArray['costArr']['baseTicketFee'] = $baseTicketFee;
        $this->_dataArray['costArr']['baseBaf'] = sprintf('%.3f', $baseBaf);;
        $totalCost = sprintf('%.3f', $baseCost + $baseTicketFee + $baseBaf + $this->_dataArray['costArr']['addCost'] + $this->_dataArray['costArr']['pCost'] + $this->_dataArray['costArr']['regCost']);
        $this->_dataArray['costArr']['totalCost'] = $totalCost;
    }

    /* @todo：判断客户是否配置了自己的价格
     * @return boolean or string
     */
    protected function hasCustomerPrice() {
        if( !isset( $this->_paramsArray['customerCode'] ) || empty( $this->_paramsArray['customerCode'] )
            || !isset( $this->_paramsArray['warehouseId'] ) || empty( $this->_paramsArray['warehouseId'] )
            || !isset( $this->_paramsArray['smCode'] ) || empty( $this->_paramsArray['smCode'] ) ) {
            return false;
        }

        $customerCode = $this->_paramsArray['customerCode'];
        //检查一下注册表,取注册人作为物流价格的客户代码
        $ownerCustomerCode = Service_CustomerProcess::getOwner( $this->_paramsArray['customerCode'] );
        if( $ownerCustomerCode ) {
            $customerCode = $ownerCustomerCode;
        }

        $condition = array(
            'customer_code' => $customerCode,
            'warehouse_id' => $this->_paramsArray['warehouseId'],
            'sm_code' => $this->_paramsArray['smCode'],
        );
        $row = Service_ShipCustomerPriceConfig::getByCondition( $condition );
        if( $row ) {
            return $customerCode;
        } else {
            return false;
        }
    }

}