<?php
/* @desc；费用项目处理
 * @author:gilbert
 * @date:2016-06-28
 */
class Service_OtherFeeProcess {
    //属性类型
    static $attributeType = array('1'=>'固定值','2'=>'无序范围值','3'=>'有序范围值','4'=>'数据表');
    protected $_param = null;//添加保险项目的数据
    protected $_error = array();//错误信息
    protected $_date = null;
    protected $_user = null;
    protected $_warehouseId = null;
    protected $_code = null;
    protected $_keepRate = 0;//是否保持跟冻结费用时一样的汇率 0否 1是
    protected $_rate = 1;//汇率


    public function __construct() {
        $this->_date = date('Y-m-d H:i:s');
        $userId = Service_User::getUserId();
        $this->_user = Service_User::getByField( $userId );
    }

    protected function setParam( $param = array() ) {
        $this->_param = $this->trimParam( $param );

    }

    protected function setWarehouse( $warehouse ) {
        $this->_warehouseId = trim( $warehouse );
    }

    protected function setCode( $code ) {
        $this->_code = trim( $code );
    }

    public function setKeepRate( $keep ) {
        $this->_keepRate = $keep;
    }

    public static function getRate( $currency, $keepRate, $refCode) {
        if( $currency == 'RMB')
            return 1;

        $currencyCacheRows          = Common_DataCache::getCurrency();
        if( $keepRate == 1 ) {
            if( is_null( $refCode ) || $refCode === '' )
                return false;

            $costRecordingRow       = Service_CostRecording::getByField( $refCode, 'order_code', array('currency_code', 'currency_rate', 'price_batch_number', 'currency_batch_number', 'sm_baf', 'provider_currency_code', 'provider_currency_rate'));
            if( empty( $costRecordingRow ) )
                return false;

            $currency_batch_number  = $costRecordingRow['currency_batch_number'];
            $currencyLogRows        = Service_CurrencyLog::getByBatchnumber($currency_batch_number);

            if(empty($currencyLogRows) || !isset( $currencyLogRows[ $currency ]['currency_rate'] ))
                return false;

            return $currencyLogRows[ $currency ]['currency_rate'];
        } else {
            return isset( $currencyCacheRows[$currency]['currency_rate'] ) ? $currencyCacheRows[$currency]['currency_rate'] : false;
        }
    }

    protected function trimParam( $param ) {
        if( is_scalar($param) ) {
            return trim($param);
        } else {
            foreach( $param as $key=>$value) {
                if( is_scalar($value) ) {
                    $param[$key] = trim($value);
                } else {
                    $param[$key] = $this->trimParam( $value );
                }
            }
            return $param;
        }
    }

    //检查数据是否为空、null、未设置
    protected function checkParam( $param,$columns ) {
        $passed = true;
        foreach( $columns as $key ) {
            if( isset( $param[$key] )) {
                if( is_null( $param[$key] ) ) {
                    $passed = false;
                    break;
                } else if( is_scalar( $param[$key] ) ) {
                    if( $param[$key] === '') {
                        $passed = false;
                        break;
                    }
                }else if( is_array( $param[$key])) {
                    $passed = $this->checkParam( $param[$key], array_keys( $param[$key] ) );
                    if( !$passed )
                        break;
                }
            } else {
                $passed = false;
                break;
            }
        }
        return $passed;
    }


    private function checkAttribute() {
        $item = array();
        if( !isset( $this->_param['warehouse'] ) || $this->_param['warehouse'] === '' ){
            $this->_error[] = '仓库不能为空';
        }

        if( !isset( $this->_param['itemCode'] ) || $this->_param['itemCode'] === '' ){
            $this->_error[] = '费用项目不能为空';
        } else {
            $item = Service_OtherFee::getByField( $this->_param['itemCode'], 'fee_code');
            if( empty($item)  ) {
                $item = array();
                $this->_error[] = '费用代码不存在';
            } else if ( $this->_param['warehouse'] != $item['warehouse_id'] ) {
                $item = array();
                $this->_error[] = '仓库没有这个费用代码';
            }
        }
        if( empty( $item ) ) return;

        $this->_param['item'] = $item;

        if( !isset( $this->_param['attributeNameCn'] ) || $this->_param['attributeNameCn'] === '' ) {
            $this->_error[] = '至少要有一个属性';
        } else if( !is_array( $this->_param['attributeNameCn'] ) ) {
            $this->_error[] = '数据异常';
        } else {
            if( !isset( $this->_param['aType'] ) ) {
                $this->_param['aType'] = array();
            }
            $attribute = array();
            $aType = array();
            $aTypeKey = array_keys( self::$attributeType );
            $tableTypeCnt = 0;
            foreach( $this->_param['attributeNameCn'] as $key => $value ) {
                if( !is_scalar( $value ) ) {
                    $this->_error[] = '数据异常';
                    break;
                }

                if( $value === '' ) {
                    $this->_error[] = '存在空数据';
                    break;
                }
                if( in_array( $value, $attribute ) ) {
                    $this->_error[] = '存在相同属性【'.$value.'】';
                    continue;
                }
                if( !isset( $this->_param['variable'][$key] ) || $this->_param['variable'][$key] === '' ) {
                    $this->_error[] = '属性'.$value.'缺少变量名';
                    continue;
                } else if( !preg_match('/^[a-zA-Z]+\w?$/',$this->_param['variable'][$key])) {
                    $this->_error[] = '属性'.$value.'变量名只能有英文字母和数字组成，且以字母开头';
                    continue;
                }

                $aRow = Service_OtherFeeAttribute::getByCondition( array( 'fee_id'=>$item['fee_id'], 'ofa_name'=>$value ) );
                $bRow = Service_OtherFeeAttribute::getByCondition( array( 'fee_id'=>$item['fee_id'], 'ofa_variable'=> $this->_param['variable'][$key] ) );
                if( $aRow || $bRow) {
                    $this->_error[] = '费用项目【'.$item['fee_name'].'】已存在属性【'.$value.'】';
                } else {
                    $attribute[$key] = $value;
                    $aType[$key] = isset( $this->_param['aType'][$key] ) && in_array( $this->_param['aType'][$key], $aTypeKey ) ? $this->_param['aType'][$key] : 1;
                    if( $aType[$key] == 4 ) {
                        if( !isset( $this->_param['dataTable'][$tableTypeCnt]) || empty( $this->_param['dataTable'][$tableTypeCnt] ) ) {
                            $this->_error[] = '属性'.$value.'缺少文件模板名';
                        }
                        ++$tableTypeCnt;
                    }
                }
            }
        }
    }

    /* @todo:添加项目属性
     * @date:2016-07-08
     * @param array $param 属性数据
     * @return array
     */
    public function addAttribute( $param ) {
        $return = array('ask'=>0,'message'=>'','error'=>array());

        $this->setParam( $param );
        $this->checkAttribute();

        if( !empty( $this->_error ) ) {
            $return['message'] = '添加失败';
            $return['error'] = $this->_error;
            return $return;
        }

        $adapter = Common_Common::getAdapter();
        $adapter->beginTransaction();

        try {
            $dataTableCnt = 0;
            foreach( $this->_param['attributeNameCn'] as $key => $value ) {
                $template = '';
                if( $this->_param['aType'][$key] == 4 ) {
                    $template = $this->_param['dataTable'][$dataTableCnt];
                }
                $addItem = array(
                    'fee_id'                => $this->_param['item']['fee_id'],
                    'ofa_name'             => $value,
                    'ofa_value_type'      => $this->_param['aType'][$key],
                    'ofa_variable'        => $this->_param['variable'][$key],
                    'ofa_add_time'        => $this->_date,
                    'ofa_template_name'  => $template,
                );
                $addResult = Service_OtherFeeAttribute::add( $addItem );
                //写日志
                $log = array(
                    'fee_id'                => $this->_param['item']['fee_id'],
                    'ofl_remark'    => '费用项目'.$this->_param['item']['fee_name'].'增加属性'.$value,
                    'user_id'        => $this->_user['user_id'],
                    'ip'             => Common_Common::getIP(),
                    'ofl_add_time' => $this->_date,
                );
                $addLogResult = Service_OtherFeeLog::add( $log );
                if( !$addLogResult )
                    throw new Exception( '添加日志失败' );
            }

            $adapter->commit();
            $return['ask'] = 1;
            $return['message'] = '添加成功';
        } catch( Exception $e ) {
            $adapter->rollBack();
            $return['message'] = '添加失败';
            $return['error'][] = $e->getMessage();
        }
        return $return;

    }

    private function checkEditConfig() {
        if( isset( $this->_param['itemId'] ) && $this->_param['itemId'] === '' ) {
            $this->_error[] = '数据异常';
        } else {
            $item = Service_OtherFee::getByField( $this->_param['itemId'] );
            if( !$item ) {
                $this->_error[] = '费用项目不存在';
            }
        }
    }

    /* @todo；修改配置
     *
     */
    public function editConfig( $param ) {
        $return = array('ask'=>0,'message'=>'','error'=>array());

        $this->setParam( $param );
        $this->checkEditConfig();

        if( !empty( $this->_error ) ) {
            $return['message'] = '更新失败';
            $return['error'] = $this->_error;
            return $return;
        }

        $difference = $this->getConfigDifference();
        $dataTable  = $this->getDataTable();

        if( empty( $difference ) && empty( $dataTable ) ) {
            $return['message'] = empty($this->_error) ? '无变化' : '更新失败';
            $return['error'] = $this->_error;
            return $return;
        }

        $adapter = Common_Common::getAdapter();
        $adapter->beginTransaction();
        try {
            //要更新的数据
            if( isset( $difference['update'] ) ) {
                foreach( $difference['update'] as $configId => $value) {
                    $update = $value;
                    $update['ofc_update_time'] = $this->_date;
                    $result = Service_OtherFeeConfig::update( $update, $configId );
                    if( !$result )
                        throw new Exception( '更新失败' );
                }
            }
            //新加的属性
            if( isset( $difference['add'] ) ) {
                foreach( $difference['add'] as  $value) {
                    $result = Service_OtherFeeConfig::add( $value );
                    if( !$result )
                        throw new Exception( '更新失败' );
                }
            }
            //数据表类型的都是想删除所有的数据，再重新添加
            if( !empty( $dataTable ) ) {
                foreach( $dataTable as $id => $data ) {
                    //判断是否是新加的属性
                    if( $row = Service_OtherFeeConfigTable::getByField( $id, 'ofa_id' ) ) {
                        //先删除旧的数据表
                        $dResult = Service_OtherFeeConfigTable::delete($id,'ofa_id');
                        if( !$dResult )
                            throw new Exception( '更新失败' );
                    }
                    foreach( $data as $value) {
                        $add = $value;
                        $add['ofct_add_time'] = $this->_date;
                        $aResult = Service_OtherFeeConfigTable::add( $add );
                        if( !$aResult )
                            throw new Exception( '更新失败' );
                    }
                }
            }

            //写日志
            $log = array(
                'fee_id'          => $this->_param['itemId'],
                'ofl_remark'    => '更新费用项目配置',
                'user_id'        => $this->_user['user_id'],
                'ip'             => Common_Common::getIP(),
                'ofl_add_time' => $this->_date,
            );
            $addLogResult = Service_OtherFeeLog::add( $log );
            if( !$addLogResult )
                throw new Exception( '添加日志失败' );

            $adapter->commit();
            $return['ask'] = 1;
            $return['message'] = '更新成功';
        } catch ( Exception $e ) {
            $adapter->rollBack();
            $return['message'] = '更新失败';
            $return['error'][] = $e->getMessage();
        }
        return $return;
    }

    /* @todo:比较配置
     * @return array
     */
    private function getConfigDifference() {
        $difference = array();
        if( !isset( $this->_param['attribute'] ) || empty( $this->_param['attribute'] ) )
            return $difference;
        //取出所有费用项目的所有属性，和页面传来的数据进行比较
        $attribute = $this->_param['attribute'];
        $columns = array('ofc_id','ofc_value','ofc_value_start','ofc_value_end','ofc_value_eq_start','ofc_value_eq_end','ofc_disordered_value');
        $config = Service_OtherFeeAttribute::leftJoinConfig( array('fee_id'=>$this->_param['itemId']),'*',$columns);

        $update = $add = array();
        //print_r($config);
        //print_r($attribute);
        foreach( $config as $value) {

            $id = $value['ofa_id'];
            $configId = $value['ofc_id'];
            if( isset( $attribute[ $id ] ) ) { //取出的属性里可能会有类型是数据表的属性，页面传来的数据表保存在$_FILES，而不是 $attribute
                //如果没有配置ID的，就是后续新加的属性。因为第一次配置时，所有的属性都会被配置。
                if( $configId ) {
                    if(  $value['ofa_value_type'] == 1 ) {
                        if( $value['ofc_value'] != $attribute[ $id ] )
                            $update[ $configId ] = array('ofc_value'=>$attribute[ $id ]);
                    } else if ( $value['ofa_value_type'] == 2 ) {
                        if( $value['ofc_disordered_value'] != $attribute[ $id ] )
                            $update[ $configId ] = array('ofc_disordered_value'=>$attribute[ $id ]);

                    } else if( $value['ofa_value_type'] == 3 ) {
                        if( $value['ofc_value_start'] != $attribute[ $id ][0] ) {
                            $update[ $configId ]['ofc_value_start'] = $attribute[ $id ][0];
                        }
                        if( $value['ofc_value_end'] != $attribute[ $id ][1] ) {
                            $update[ $configId ]['ofc_value_end'] = $attribute[ $id ][1];
                        }
                        if( isset( $this->_param['compareStart'][ $id ] ) && in_array( $this->_param['compareStart'][ $id ],array(1,2)) && $value['ofc_value_eq_start'] != $this->_param['compareStart'][ $id ] ) {
                            $update[ $configId ]['ofc_value_eq_start'] = $this->_param['compareStart'][ $id ];
                        }
                        if(isset( $this->_param['compareEnd'][ $id ] ) && in_array( $this->_param['compareEnd'][ $id ],array(1,2)) && $value['ofc_value_eq_end'] != $this->_param['compareEnd'][ $id ] ) {
                            $update[ $configId ]['ofc_value_eq_end'] = $this->_param['compareEnd'][ $id ];
                        }
                    }
                } else {
                    $addData= array(
                        'fee_id'=>$this->_param['itemId'],
                        'ofa_id'=>$id,
                        'ofc_add_time'=>$this->_date
                    );
                    if( $value['ofa_value_type'] == 1 ) {
                        $addData['ofc_value'] = $attribute[ $id ];

                    } else if( $value['ofa_value_type'] == 2 ) {
                        $addData['ofc_disordered_value'] = $attribute[ $id ];

                    } else {
                        $addData['ofc_value_start'] = $attribute[ $id ][0];
                        $addData['ofc_value_end'] = $attribute[ $id ][1];
                        $addData['ofc_value_eq_start'] = isset( $this->_param['compareStart'][ $id ] ) && in_array($this->_param['compareStart'][ $id ],array(1,2)) ? $this->_param['compareStart'][ $id ] : 1;
                        $addData['ofc_value_eq_end'] = isset( $this->_param['compareEnd'][ $id ] ) && in_array($this->_param['compareEnd'][ $id ],array(1,2)) ? $this->_param['compareEnd'][ $id ] : 1;
                    }
                    $add[] = $addData;
                }
            }
        }
        if( $update )
            $difference['update'] = $update;
        if( $add )
            $difference['add'] = $add;

        return $difference;
    }

    /* @todo:获取数据表数据
     * @return array
     */
    private function getDataTable() {
        $data = array();
        if(!empty( $_FILES ) && isset( $_FILES['attach'])) {
            $tmpFileArr = $_FILES['attach']['tmp_name'];
            try {
                foreach( $tmpFileArr as $id => $file ) {
                    if( !$file ) continue;

                    if( file_exists( $file ) &&  $handle = fopen( $file, "r" )) {
                        $cnt = 0;
                        $selfAttr = array();
                        while( false !== ( $row = fgetcsv( $handle,0,',') ) ) {
                            $encoding = '';//文件编码
                            //处理数据体
                            foreach ( $row as $key => $value ) {
                                //判断第一行(即标题）是不是费用项目自带的属性，如果标题是费用自带的属性，就会在fict_ref_id写入值；如果不是，就会直接把标题写入fict_ref_code
                                if( $cnt == 0 ) {
                                    if( $value ) {
                                        $encoding = mb_detect_encoding( $value,array('ASCII','GB2312','GBK','UTF-8'));
                                        if( $encoding === false)
                                            throw new Exception( '文件编码必须是（ASCII、GB2312、GBK、UTF-8）之中一个');

                                        $tmpValue = mb_convert_encoding($value,'utf-8',$encoding);

                                        $attribute = Service_OtherFeeAttribute::getByCondition( array( 'fee_id' => $this->_param['item']['fee_id'], 'ofa_name' => $tmpValue ));
                                        if( $attribute ) {
                                            $selfAttr[$key] = $attribute[0];
                                        } else {
                                            $selfAttr[$key] = $tmpValue;
                                        }
                                    } else {
                                        $selfAttr[$key] = $value;
                                    }

                                } else {
                                    $encoding = mb_detect_encoding( $value,array('ASCII','GB2312','GBK','UTF-8'));
                                    if( $encoding === false)
                                        throw new Exception( '文件编码必须是（ASCII、GB2312、GBK、UTF-8）之中一个');

                                    //转换编码，防止写入乱码
                                    $tmpValue = mb_convert_encoding($value,'utf-8',$encoding);

                                    $add = array(
                                        'fee_id'         => $this->_param['itemId'],
                                        'ofa_id'        => $id,
                                        'ofct_value'   => $tmpValue,
                                    );
                                    if( is_array( $selfAttr[$key] ) ) {
                                        $add['ofct_ref_id'] = $selfAttr[$key]['ofa_id'];//费用自带的属性
                                        $add['ofct_ref_code'] = '';
                                    } else {
                                        $add['ofct_ref_code'] = $selfAttr[$key];//非自带属性
                                        $add['ofct_ref_id'] = 0;
                                    }
                                    $data[ $id ][] = $add;
                                }
                            }
                            ++$cnt;
                        }
                        fclose($handle);
                    } else {
                        $data = array();
                        break;
                    }
                }
            } catch( Exception $e) {
                $data = array();
                $this->_error[] = $e->getMessage();
            }
        }
        return $data;
    }

    protected function getConfig( $warehouseId, $code, $index = array() ) {
        $config = array();
        if( empty($warehouseId) || empty($code))
            return false;

        $codes = array();
        if( is_scalar( $code ) )
            $codes = array( $code );
        else
            $codes = $code;

        $column = array('ofa_id','ofa_name','ofa_variable','ofa_value_type');

        foreach( $codes as $code ) {
            $item = Service_OtherFee::getByField( $code, 'fee_code');
            if( empty( $item ) || $item['warehouse_id'] != $warehouseId ) {
                $config[ $code ] = false;
                continue;
            }

            $config[ $code ] = $item;

            $attribute = Service_OtherFeeAttribute::getByCondition(array('fee_id'=>$item['fee_id']),$column);
            if( empty( $attribute ) ){
                $config[ $code ]['attribute'] = array();
                continue;
            }

            foreach($attribute as $key=>$value){

                $config[ $code ]['attribute'][ $value['ofa_variable'] ]['ofa_name'] = $value['ofa_name'];
                $config[ $code ]['attribute'][ $value['ofa_variable'] ]['ofa_value_type'] = $value['ofa_value_type'];

                if( $value['ofa_value_type'] == 4 ) {
                    $configTable = Service_OtherFeeConfigTable::getByCondition( array('fee_id'=>$value['fee_id'],'ofa_id'=>$value['ofa_id']));
                    if( $configTable ) {
                        $columnData = $rowData = array();
                        foreach( $configTable as $k => $v ) {
                            $text = $v['ofct_ref_code'];
                            if( $v['ofct_ref_id'] ) {
                                $tmpRow = Service_OtherFeeAttribute::getByField($v['ofct_ref_id']);
                                $text = $tmpRow['ofa_variable'];
                            }
                            $columnData[$text][] = $v;
                        }
                        //行转列(数据表是的内容是列转行保存下来的)
                        $rows = count($configTable) / count($columnData);
                        $keys = array_keys($columnData);

                        $s = false;
                        if( isset( $index[ $code ][ $value['ofa_variable'] ] ) && $index[ $code ][ $value['ofa_variable'] ] !== '')
                            $s = array_search( $index[ $code ][ $value['ofa_variable'] ],$keys);

                        for( $i=0; $i<$rows; $i++ ) {
                            $tmpIndex = $s !== false ? $columnData[ $keys[$s] ][$i]['ofct_value'] : $i;
                            foreach($keys as $k=>$v) {
                                $rowData[ $tmpIndex ][$k] = $columnData[$v][$i]['ofct_value'];
                            }
                        }
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value'] = $rowData;
                    } else {
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value'] = array();
                    }

                } else {
                    $configRow = Service_OtherFeeConfig::getByCondition( array('fee_id'=>$value['fee_id'],'ofa_id'=>$value['ofa_id']));
                    if( empty($configRow) ) {
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value'] = array();
                        continue;
                    }

                    if( $value['ofa_value_type'] == 1 ) {
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value'] = $configRow[0]['ofc_value'];

                    } else if( $value['ofa_value_type'] == 2) {
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value'] = $configRow[0]['ofc_disordered_value'];

                    } else {
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value']['start'] = $configRow[0]['ofc_value_start'];
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value']['end'] = $configRow[0]['ofc_value_end'];
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value']['eqStart'] = $configRow[0]['ofc_value_eq_start'];
                        $config[ $code ]['attribute'][ $value['ofa_variable'] ]['value']['eqEnd'] = $configRow[0]['ofc_value_eq_end'];
                    }
                }
            }
        }
        return $config;

    }

    public function getError() {
        return $this->_error;
    }

    public function getAmount($warehouseId,$code,$param=array(),$keepRate = 0) {
        $amount = false;
        $this->setWarehouse( $warehouseId );
        $this->setCode( $code );
        $this->setParam( $param );
        $this->setKeepRate( $keepRate );
        switch( $this->_code ) {
            case 'GTI':
            case 'ODI':
            case 'OCI':
            case 'GRI':
                $amount = $this->getInsuranceAmount();
                break;
        }
        return $amount;
    }

    //获取保险费
    public function getInsuranceAmount() {
        /* 费用代码说明
         * GTI:货物运输保险
         * ODI:订单延误保险
         * OCI:订单取消保险
         * GRI:产品责任险
         */
        //amount保费 premium投保金额，detail保费明细 要注意的是，如果有错，是直接返回 初始时的 $return
        if( $this->_warehouseId === '' || $this->_code === '' )
            return false;
        //检查参数
        $result = $this->checkParam( $this->_param, array('insuranceRate','country','dealPrice','dealCurrency','orderCode'));
        if( !$result ) {
            $this->_error[] = '计费参数不全';
            return false;
        }
        $countryId = $this->_param['country'];//订单国家
        $dPrice = $this->_param['dealPrice'];//成交总价
        $iRate = $this->_param['insuranceRate'];//投保金额率
        $dCurrency = strtoupper( $this->_param['dealCurrency'] );//成交币种

        //获取汇率
        $this->_rate = self::getRate( $dCurrency, $this->_keepRate,$this->_param['orderCode'] );

        //获取地区
        $areaCode =  $this->getArea( $countryId );
        if( $areaCode === false || $areaCode === '' || is_null($areaCode)) {
            $this->_error[] = '国家区域代码为空';
            return false;
        }
        //获取相关保险费代码
        $codes    =  $this->getInsuranceCode( $this->_code );

        //获取配置
        $config = $this->getConfig( $this->_warehouseId, $codes, array('ODI'=>array('price'=>'区域')));
        if( $config === false ) {
            $this->_error[] = '获取杂费配置失败';
            return false;
        }
        //投保金额
        $premium = sprintf( '%.2f', $dPrice * $this->_rate * $iRate );//投保金额 = 成交总价*投保金额率
        //print_r($config);
        $amount = array();
        foreach( $config as $code => $value ) {
            //费用代码不存在的，或没有属性的，或费用类型代码不是保险费的
            if( $value === false || empty( $value['attribute'] ) || $value['ft_code'] != 'SI') {
                $this->_error[] = '费用类型代码不是SI';
                return false;
            }

            $name = $value['fee_name'];

            //判断计费类型
            if( !isset( $value['attribute']['chargeType']['value'] ) || $value['attribute']['chargeType']['value'] === '' ) {
                $this->_error[] = '杂费配置-收费类型不能为空';
                return false;
            }

            //如果保险费可用状态 或过了有效期时间，费用写0
            if( $value['status'] != 1 ) {
                if( $code == 'ODI') {//延误险的价格表本身就是RMB
                    $amount[] = array( 'feeCode'=>$code, 'name' => $name, 'amount' => 0,'cost'=>0,'currency'=>'RMB');
                } else {
                    $amount[] = array( 'feeCode'=>$code, 'name' => $name, 'amount' => 0,'cost'=>0,'currency'=>'RMB');
                }
                continue;
            }

            //区域收费的直接取报价表的报价,价格表本身就是RMB币种
            if( $value['attribute']['chargeType']['value'] == '区域收费' ) {
                if( isset( $value['attribute']['price']['value'][$areaCode] ) ) {
                    $cost = $value['attribute']['price']['value'][$areaCode][1];//成本
                    $price = $value['attribute']['price']['value'][$areaCode][2];//报价
                    //配置属性时没对数据做检查的，所以这里要检查一下
                    if( !is_numeric($cost) || !is_numeric($price) ) {
                        $this->_error[] = '杂费配置-价格表的成本或价格必须是数字';
                        return false;
                    }
                    //$amount[] = array( 'feeCode'=>$code, 'name' => $name, 'amount' => sprintf('%0.2f',$price * $value['fee_discount']) , 'cost'=>$cost,'currency'=>'RMB');
                    $amount[] = array( 'feeCode'=>$code, 'name' => $name, 'amount' => sprintf('%0.2f',$price ) , 'cost'=>$cost,'currency'=>'RMB');
                } else {
                    $this->_error[] = '杂费未配置区域价格';
                    return false;
                }
                //阶段收费的，费用=(投保金额/阶段金额)*阶段金额率 ，注意 投保金额/阶段金额 如果不是整数，要向上取整：2.1 => 3
            } else if( $value['attribute']['chargeType']['value'] == '阶段收费' ){
                if( !isset( $value['attribute']['intervalAmount']['value'] )
                    || !is_numeric($value['attribute']['intervalAmount']['value'])
                    || $value['attribute']['intervalAmount']['value'] <= 0
                    || !isset( $value['attribute']['intervalRate']['value'] )
                    || !is_numeric($value['attribute']['intervalRate']['value'])
                    || $value['attribute']['intervalRate']['value'] <= 0 ) {
                    $this->_error[] = '阶段金额和阶段金额率必须是大于0的数字';
                    return false;
                }
                $base = ceil( $premium / $value['attribute']['intervalAmount']['value'] );
                $price = sprintf('%.2f', $base * $value['attribute']['intervalRate']['value'] );//报价 = ceil( 投保金额 / 阶段金额 ) * 阶段金额费率
                $cost = sprintf('%.2f', $premium * $value['attribute']['insuranceRate']['value']);// 成本 = 投保金额*保费费率

                //$amount[] = array( 'feeCode'=>$code, 'name' => $name, 'amount' => sprintf('%0.2f',$price * $value['fee_discount']) ,'cost'=>$cost,'currency'=>'RMB');
                $amount[] = array( 'feeCode'=>$code, 'name' => $name, 'amount' => sprintf('%0.2f',$price) ,'cost'=>$cost,'currency'=>'RMB');
            } else if ($value['attribute']['chargeType']['value'] == '百分比收费') {
                if (!isset($value['attribute']['intervalAmount']['value'])
                    || !is_numeric($value['attribute']['intervalAmount']['value'])
                    || $value['attribute']['intervalAmount']['value'] <= 0
                    || !isset($value['attribute']['intervalRate']['value'])
                    || !is_numeric($value['attribute']['intervalRate']['value'])
                    || $value['attribute']['intervalRate']['value'] <= 0
                ) {
                    $this->_error[] = '费用项目[' . $value['fee_name'] . ']系统设置异常';
                    return false;
                }
                $price = sprintf('%.2f', $premium * $value['attribute']['intervalRate']['value'] * 0.01);
                $price = ($price > $value['attribute']['intervalAmount']['value']) ? $price : sprintf('%.2f', $value['attribute']['intervalAmount']['value']);
                $cost = sprintf('%.2f', $premium * $value['attribute']['insuranceRate']['value'] * 0.01);
                $amount[] = array( 'feeCode'=>$code, 'name' => $name, 'amount' => sprintf('%0.2f',$price) ,'cost'=>$cost,'currency'=>'RMB');
            } else {
                $this->_error[] = $name.'收费类型不正确';
                return false;
            }
        }
        return $amount;
    }

    protected function getArea( $countryId ) {
        if( $countryId ) {
            $country = Service_Country::getByField( $countryId );
            if( empty( $country ) ||  empty ( $country['country_area']) )
                return false;
            else
                return $country['country_area'];

        }
        return false;
    }

    protected function getInsuranceCode( $code ) {
        $codes = array( $code );
        //某些保险要连带购买
        if( $this->_code == 'ODI') {
            $codes[] = 'GTI';
        } else if( $this->_code == 'OCI' ) {
            $codes[] = 'GTI';
            $codes[] = 'ODI';
        } else if( $this->_code == 'GRI' ) {
            $codes[] = 'GTI';
            $codes[] = 'ODI';
            $codes[] = 'OCI';
        }
        return $codes;
    }


  }