<?php
/**
 * @desc QC卡位费
 */
class Process_QckwfProcess
{
    protected static $_date;
    protected static $_userId;
    private static $_instance;

    public function __construct()
    {
        self::$_userId = Service_User::getUserId();
        self::$_date = date('Y-m-d');
    }

    /**
     * [getInstance description]
     * @return [type] [description]
     */
    public static function getInstance() 
    { 
        if ( is_null(self::$_instance) ) {
            self::$_instance = new self();
        } 
        return self::$_instance; 
    }
    
    /**
     * [ description]
     * @return [otherFeeCode] [description]
     */
    public static function run($otherFeeCode = 'QCKWF-02'){
        $otherFeeCode = strtoupper($otherFeeCode);
        if(empty($otherFeeCode) || !in_array($otherFeeCode, array('QCKWF-01', 'QCKWF-02'))){
            self::debug('Error: Parameter is not valid');
            return;
        }
        //self::deductQckwfFee($otherFeeCode);
        switch ($otherFeeCode) {
            /*
            // QC卡位费1 按日计算
            case 'QCKWF1':
                self::deductDayQckwfFee($otherFeeCode);
                break;
            */
            // QC卡位费2 按月计算
            case 'QCKWF-02':
                self::qckwfTwo($otherFeeCode);
                break;
            default:
                self::qckwfTwo($otherFeeCode);
                break;
        }
    }

    /**
     * 日费用
     */
    public function deductDayQckwfFee($otherFeeCode, $wcdRow){
        $return = array(
            'state' => 0,
            'message' => '',
            'errorMessage'=>array('Fail.')
        );
        $otherFeeInfo = Service_OtherFee::getByField($otherFeeCode, 'fee_code');
        if(!empty($otherFeeInfo)){
            $db = Service_WarehouseCardDay::getModelInstance()->getAdapter();
            $db->beginTransaction();
            try {
                $objOtherCalculte = new Common_CalculateOtherFee();
                $objOtherCalculte->setQcParams($wcdRow);
                $otherfeeArr = $objOtherCalculte->getOtherFee($otherFeeCode);
                $otherfeeQckwf = $otherfeeArr['data']['otherFee'][strtolower($otherFeeCode)];
                if($otherfeeQckwf['price'] > 0) {
                    if( strtoupper($wcdRow['wcd_warehouse_code']) != 'ALL' ){
                        $warehouseData = Service_Warehouse::getByField($wcdRow['wcd_warehouse_code'], 'warehouse_code', array('warehouse_id'));
                        $wcdRow['warehouse_id'] = $warehouseData['warehouse_id'];
                    }else {
                        $wcdRow['warehouse_id'] = 0;
                    }
                    $customerData = Service_Customer::getByField($wcdRow['wcd_customer_code'], 'customer_code', array('customer_id'));
                    if(empty($customerData)){
                        throw new Exception('Customer does not exist');
                    }
                    //扣费
                    $otherParam['add_time'] = $wcdRow['wcd_card_day_time']; //交易记录时间
                    $deductResult = Service_CustomerBalanceProcess::deductFee($customerData['customer_id'], $otherfeeQckwf, '扣'.$otherFeeInfo['fee_name'], $wcdRow['wcd_code'], $otherFeeCode, $otherfeeQckwf['fee_id'],$otherParam);
                    if($deductResult['ask'] !=1 ){
                        throw new Exception($deductResult['error']);
                    }
                    //处理收费业务数据
                    $paymentArr = $incomeArr = $fee_cost_detail = array();
                    $businessIncomArr = self::getBusinessAndIncom($wcdRow['wcd_customer_code'], $wcdRow['wcd_code'], $wcdRow['wcd_code'], $otherfeeQckwf, $otherFeeInfo);
                    if(!empty($businessIncomArr)){
                        if(array_key_exists('income', $businessIncomArr) && $businessIncomArr['income']){
                            $incomeArr[] = $businessIncomArr['income'];
                        }
                        if(array_key_exists('payment', $businessIncomArr) && $businessIncomArr['payment']){
                            $paymentArr[] = $businessIncomArr['payment'];
                        }
                        if(array_key_exists('cost_detail', $businessIncomArr) && $businessIncomArr['cost_detail']){
                            $fee_cost_detail[] = $businessIncomArr['cost_detail'];
                        }
                    }
                    //处理财务业务数据
                    if(!empty($incomeArr) || !empty($paymentArr)){
                        self::doBusinessPaymentIncome($wcdRow['wcd_customer_code'], $wcdRow['warehouse_id'], $wcdRow['wcd_code'], $wcdRow['wcd_card_day_num'], $incomeArr, $paymentArr, $fee_cost_detail, 0);
                    }
                    //更新收费状态
                    if(Service_WarehouseCardDay::update(array('wcd_status' => 1, 'wcd_update_time' => date('Y-m-d H:i:s')), array('wcd_id'=>$wcdRow['wcd_id'])) === false){
                        throw new Exception('单号['.$wcdRow['wcd_code'].']收费状态更新失败');
                    }
                }
                $db->commit();
                $return['state'] = 1;
                $return['message'] = 'Success.';
            }catch (Exception $e){
                $db->rollBack();
                $return['message'] = $e->getMessage();
            }
        }else {
            $return['message'] = '费用代码'.$otherFeeCode.'不存在';
        }
        return $return;
    }

    /**
     * [qckwfTwo 收取QC卡位费]
     * @return [type] [description]
     */
    private static function qckwfTwo($otherFeeCode){
        $wcmData = Service_WarehouseCardMonth::getByCondition(array('wcm_status' => 0, 'wcm_card_month_time_lt_now' => self::$_date));
        $otherFeeInfo = Service_OtherFee::getByField($otherFeeCode, 'fee_code');
        $objOtherCalculte = new Common_CalculateOtherFee();
        if(is_array($wcmData) && !empty($wcmData) && !empty($otherFeeInfo)){
            $db = Service_WarehouseCardMonth::getModelInstance()->getAdapter();
            foreach ($wcmData as $wcmRow) {
                $db->beginTransaction();
                try {
                    $objOtherCalculte->setQcParams($wcmRow);
                    $otherfeeArr = $objOtherCalculte->getOtherFee($otherFeeCode);
                    $otherfeeQckwf = $otherfeeArr['data']['otherFee'][strtolower($otherFeeCode)];
                    //$biatt = Service_BilBusinessAttach::getByField($wcmRow['wcm_code'], 'bb_refer_code');
                    $isFeeCondition = array(
                        'cbl_refer_code' => $wcmRow['wcm_code'],
                        'application_code' => $otherFeeCode,
                        'left_month_add_date' => self::$_date
                    );
                    $isFee = Service_CustomerBalanceLog::getByCondition($isFeeCondition, 'count(*)');
                    //收QC卡位费1 收取过费用将不在收取 
                    if($otherfeeQckwf['price'] > 0 && empty($isFee)) {
                        if( strtoupper($wcmRow['wcm_warehouse_code']) != 'ALL' ){
                            $warehouseData = Service_Warehouse::getByField($wcmRow['wcm_warehouse_code'], 'warehouse_code', array('warehouse_id'));
                            $wcmRow['warehouse_id'] = $warehouseData['warehouse_id'];
                        }else {
                            $wcmRow['warehouse_id'] = 0;
                        }
                        $customerData = Service_Customer::getByField($wcmRow['wcm_customer_code'], 'customer_code', array('customer_id'));
                        if(empty($customerData)){
                            throw new Exception('Customer does not exist');
                        }
                        //扣费
                        $deductResult = Service_CustomerBalanceProcess::deductFee($customerData['customer_id'], $otherfeeQckwf, '扣'.$otherFeeInfo['fee_name'], $wcmRow['wcm_code'], $otherFeeCode, $otherfeeQckwf['fee_id']);
                        if($deductResult['ask'] !=1 ){
                            throw new Exception($deductResult['error']);
                        }
                        //处理收费业务数据
                        $paymentArr = $incomeArr = $fee_cost_detail = array();
                        $businessIncomArr = self::getBusinessAndIncom($wcmRow['wcm_customer_code'], $wcmRow['wcm_code'], $wcmRow['wcm_code'], $otherfeeQckwf, $otherFeeInfo);
                        if(!empty($businessIncomArr)){
                            if(array_key_exists('income', $businessIncomArr) && $businessIncomArr['income']){
                                $incomeArr[] = $businessIncomArr['income'];
                            }
                            if(array_key_exists('payment', $businessIncomArr) && $businessIncomArr['payment']){
                                $paymentArr[] = $businessIncomArr['payment'];
                            }
                            if(array_key_exists('cost_detail', $businessIncomArr) && $businessIncomArr['cost_detail']){
                                $fee_cost_detail[] = $businessIncomArr['cost_detail'];
                            }
                        }
                        //处理财务业务数据
                        if(!empty($incomeArr) || !empty($paymentArr)){
                            self::doBusinessPaymentIncome($wcmRow['wcm_customer_code'], $wcmRow['warehouse_id'], $wcmRow['wcm_code'], $wcmRow['wc_card_day_num'], $incomeArr, $paymentArr, $fee_cost_detail, 0);
                        }
                        //更新收费状态
                        if(Service_WarehouseCardMonth::update(array('wcm_status' => 1, 'wcm_update_time' => date('Y-m-d H:i:s')), array('wcm_id'=>$wcmRow['wcm_id'])) === false){
                            throw new Exception('单号['.$wcmRow['wcm_code'].']收费状态更新失败');
                        }
                    }else {
                        throw new Exception('客户['.$wcmRow['wcm_customer_code'].']-['.$wcmRow['wcm_warehouse_code'].']卡位维护单号['.$wcmRow['wcm_code'].']应收费用为0或者当天已收取费用');
                    }
                    $db->commit();
                    self::debug('客户['.$wcmRow['wcm_customer_code'].']-['.$wcmRow['wcm_warehouse_code'].']卡位维护单号['.$wcmRow['wcm_code'].']收费['.$otherfeeQckwf['price'].']成功');
                }catch (Exception $e){
                    $db->rollBack();
                    self::debug('error：'.$e->getMessage());
                }
            }
        }
    }

    /**
     * [getBusinessAndIncom 获取费用 应收 | 应付 | 成本数组]
     * @author [simple] <[<^^^^^^^>]>
     * @param  [type] $customer_code [客户代码]
     * @param  [type] $reference_no  [追踪号]
     * @param  [type] $code_number   [单号]
     * @param  [type] $otherfeeRow   [杂费收费数组]
     * @param  [type] $otherFeeInfo  [杂费信息数组]
     * @return [type]                [description]
     */
    private static function getBusinessAndIncom($customer_code, $reference_no, $code_number,$otherfeeRow, $otherFeeInfo){
        //应收 / 应付 / 成本
        $incomeArr = $paymentArr = $fee_cost_detail = array();
        $tmpFee = str_replace('-', '', strtolower($otherFeeInfo['fee_code']));
        $_otherfee_mix_arr = Process_BillConfig::getOtherFeeArr();
        $billConfig = $_otherfee_mix_arr[$tmpFee];
        if(empty($billConfig)){
            throw new Exception('费用['.$otherFeeInfo['fee_code'].']配置错误');
        }
        $userAuth = new Zend_Session_Namespace('userAuthorization');
        $remote_ip = Common_Common::getIP();
        $customerArr = Service_Customer::getByField($customer_code, 'customer_code', array('customer_saler_user_id','customer_currency'));
        //转为客户币种
        $convert_fee = Service_Currency::converByCode($otherfeeRow['currency_code'], $customerArr['customer_currency'], $otherfeeRow['price']);
        $date = date("Y-m-d H:i:s");
        //应收
        $incomeArr = array(
            'customer_code' => $customer_code,
            'ft_code' => $billConfig['ftcode'],
            'ut_code' => $billConfig['utcode'],
            'sm_code' => '',
            'bi_amount' => $convert_fee,
            'bi_org_amount' => $otherfeeRow['price'],
            'currency_code' => $otherfeeRow['currency_code'],
            'currency_rate' => '',
            'bi_chargeable_time' => $date,
            'bi_note' => $otherFeeInfo['fee_name'],
        );
        $fee_detail = array(
            'fee_amount_customer' => $convert_fee,                                  //费用金额（客户）
            'fee_currency_code_customer' => $customerArr['customer_currency'],      //费用币种（客户）
            'discount_customer' => $otherFeeInfo['discount'],                       //折扣率（客户）（1=100%）
        );
        //应付费用  服务商不能为空
        $cost_detail = array();
        if (isset($otherfeeRow['cost']) && $otherfeeRow['cost'] > 0 && $otherFeeInfo['sp_code'] != '') {
            $spRow = Service_ServiceProvider::getByField($otherFeeInfo['sp_code'], 'sp_code');
            //$sp_currency_code = $spRow['currency_code'];
            //转为服务商币种
            $convert_fee = Service_Currency::converByCode($otherFeeInfo['fee_currency_code'], $spRow['currency_code'], $otherFeeInfo['cost']);
            $paymentArr = array(
                'sp_code' => $otherFeeInfo['sp_code'],                              //服务商代码
                'ft_code' => $billConfig['ftcode'],
                'ut_code' => $billConfig['utcode'],
                'sm_code' => '',
                'bp_amount' => $convert_fee,
                'bp_org_amount' => $otherfeeRow['cost'],
                'currency_code' => $otherFeeInfo['fee_currency_code'],
                'currency_rate' => '',
                'bp_chargeable_time' => $date,
            );
            $cost_detail = array(
                'cost_amount_org'           => $otherfeeRow['cost'],                //成本金额（原始）
                'cost_currency_code_org'    => $otherFeeInfo['fee_currency_code'],      //成本币种（原始）
                'cost_amount_sp'            => $convert_fee,                        //成本金额（服务商）
                'cost_currency_code_sp'     => $spRow['currency_code'],             //成本币种（服务商）
                'sp_code'                   => $otherFeeInfo['sp_code'],            //服务商代码
            );
        }
        if(!empty($fee_detail) || !empty($cost_detail)){
            $fee_cost_common = array(
                'code_number'                   => $reference_no,                       //单号
                'code_type'                     => 3,                                   //单号类型（1:区内单 2：区外单 3：ASN单）
                'customer_code'                 => $customer_code,                      //客户代码
                'reference_no'                  => $reference_no,                       //客户参考号
                'tracking_number'               => '',                                  //服务商单号（跟踪号）
                'sm_code'                       => '',                                  //运输方式代码
                'country_code'                  => '',                                  //国际简称（二字码）
                'fee_code'                      => $otherFeeInfo['fee_code'],           //费用编号
                'fee_name'                      => $billConfig['binote'],               //费用名称
                'fee_amount_org'                => $otherFeeInfo['price'],              //费用金额（原始）
                'fee_currency_code_org'         => $otherFeeInfo['fee_currency_code'],      //费用币种（原始）
                'price_batch_number'            => '',                                  //运输价格编号
                'currency_batch_number'         => '',                                  //货币汇率编号
                'fee_time'                      => $date,                               //扣费时间
                'fee_time_recalculate'          => $date,                               //重新扣费时间
                'ip'                            => $remote_ip,                          //扣费操作IP
                'ip_recalculate'                => $remote_ip,                          //重新扣费操作IP
                'operator'                      => $userAuth->user['user_name'],        //扣费操作人
                'operator_recalculate'          => $userAuth->user['user_name'],        //重新扣费操作人
            );
            $fee_cost_detail = array_merge($fee_detail, $cost_detail, $fee_cost_common);
        }
        return array(
            'income' => $incomeArr,
            'payment' => $paymentArr,
            'cost_detail' => $fee_cost_detail
        );
    }

    /**
     * [doBusinessPaymentIncome 处理财务业务数据customer_code]
     * @param  [type] $customer_code   [客户代码]
     * @param  [type] $warehouse_id    [仓库代码]
     * @param  [type] $bb_refer_code   [追踪号]
     * @param  [type] $bb_pieces       [数量]
     * @param  [type] $incomeArr       [应收]
     * @param  [type] $paymentArr      [应付]
     * @param  [type] $fee_cost_detail [成本]
     * @param  [type] $weight          [重量]
     * @return [type]                  [description]
     */
    private static function doBusinessPaymentIncome($customer_code, $warehouse_id, $bb_refer_code, $bb_pieces, $incomeArr, $paymentArr, $fee_cost_detail, $weight){
        $customerArr = Service_Customer::getByField($customer_code, 'customer_code', array('customer_saler_user_id','customer_currency'));
        //判断是否存在应收、应付
        if(!empty($incomeArr) || !empty($paymentArr)){
            //写入业务表
            $businessArr = array(
                'ds_code' => 'ot',
                'customer_code' => $customer_code,
                'warehouse_id' => $warehouse_id,
                'sm_code' => '',
                'bb_volume_weight' => $weight,
                'bb_charge_weight' => $weight,
                'bb_delivered_weight' => $weight,
                'bb_pieces' => $bb_pieces,
                'bb_declared_value' => 0,
                'bb_declared_currency_code' => $incomeArr['currency_code'],
                'country_code' => '',
                'bb_postcode' => '',
                'bb_charge_time' => date("Y-m-d H:i:s"),
                'bb_declared_time' => date('Y-m-d H:i:s'),          //发货时间 此时间与服务商对接
                'bb_sales_id' => $customerArr['customer_saler_user_id'],
                'bb_refer_code' => $bb_refer_code,
                'bb_service_number' => '', //ref_tracking_number
                'bb_reference_no' => '',
            );
            $bsObj = new Process_Business();
            $businessResult = $bsObj->businessFee($businessArr, $incomeArr, $paymentArr);
            if($businessResult['state']!='1'){
                throw new Exception($businessResult['message']);
            }
        }
        //插入成本数据
        if(!empty($fee_cost_detail)){
            if(Service_FeeCostDetail::addMultiRows($fee_cost_detail) === false){
                throw new Exception('成本写入异常');
            }
        }
    }

    /**
     * [debug 调试输出]
     * @param  [type] $msg [description]
     * @return [type]      [description]
     */
    public static function debug($message = '')
    {
        echo '['.date('Y-m-d H:i:s').']'.$message . "\n\t";
    }

    /**
     * 浏览器友好的变量输出
     * @param mixed $var 变量
     * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串
     * @param string $label 标签 默认为空
     * @param boolean $strict 是否严谨 默认为true
     * @return void|string
     */
    public static function dump($var, $echo=true, $label=null, $strict=true) {
        $label = ($label === null) ? '' : rtrim($label) . ' ';
        if (!$strict) {
            if (ini_get('html_errors')) {
                $output = print_r($var, true);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            } else {
                $output = $label . print_r($var, true);
            }
        } else {
            ob_start();
            var_dump($var);
            $output = ob_get_clean();
            if (!extension_loaded('xdebug')) {
                $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            }
        }
        if ($echo) {
            echo($output);
            return null;
        }else
            return $output;
    }
}