<?php

class Common_CustomerFeeProcess
{
    /*
     * @desc 客户费用处理
     * @params $customerCode 客户代码 $options=>数组 支持多维
     * $options['cbl_type'] 费用类型:0:冻结; 1:解冻; 2:扣款; 3:入款
     * $options['cbl_value'] 费用金额;
     * $options['currency_code'] 费用币种;
     * $options['release_value'] 解冻费用（只支持费用类型为2，先回退再扣款）;
     * $options['user_id'] 操作人员;后台操作人员ID/0系统操作/-1客户操作;
     * $options['cbl_refer_code'] 参考号:orderCode ASNCode;
     * $options['application_code'] 操作类型;
     * $options['cbl_note'] 备注信息;
     * $options['transaction_number'] 银行交易号
     * $options['arrive_time'] 到账日期
     * @return array('state','message','data'=>array('customer_code','cb_value','cb_hold_value','currency_code'))
     */
    public static function payment($customerCode = '', $options = array(), $opType = 0)
    { 
        $return = array(
            'state' => 0,
            'message' => '',
            'data' => array()
        );
        try {
            if (empty($customerCode)) {
                $return['message'] = 'Customer code can not be empty.';
                return $return;
            }
            $customerRow = Service_Customer::getByField($customerCode, 'customer_code', array('customer_code', 'customer_id', 'customer_currency'));
            if (empty($customerRow)) {
                $return['message'] = 'CustomerCode:' . $customerCode . ' can not be found.';
                return $return;
            }
            //客户币种
            $currencyCode = $customerRow['customer_currency'];
            //参数
            $detail = array(
                'cbl_type' => '',
                'cbl_value' => 0,
                'currency_code' => '',
                'release_value' => '0',
                'currency_rate' => '',
                'user_id' => '',
                'cbl_refer_code' => '',
                'application_code' => '',
                'fee_id' => '0',
                'cbl_note' => '',
                'transaction_number' => '',
                'arrive_time' => '',
            );
            $date = date('Y-m-d H:i:s');
            $detail['cbl_add_time'] = $date;
            $userId = Service_User::getUserId();
            //数组转多组
            $optionArr = Common_Common::multiArr($options);
            $detailArr = array();
            foreach ($optionArr as $option) {
                $tmpDetail = $detail;
                foreach ($option as $key => $val) {
                    if (isset($detail[$key]) && $val !== '' && !is_array($val)) {
                        $tmpDetail[$key] = $val;
                    }
                    if (!is_numeric($tmpDetail['cbl_value'])) {
                        $return['message'] = 'Fee can not be null.';
                        return $return;
                    }
                    if (!in_array($tmpDetail['cbl_type'], array(0, 1, 2, 3, 6 ,8))) {
                        $return['message'] = 'FeeType:' . $tmpDetail['cbl_type'] . ' can not be found.';
                        return $return;
                    }
                }
                $detailArr[] = $tmpDetail;
            }
            unset($optionArr, $tmpDetail);

            //写入日志
            $balanceRow = Service_CustomerBalance::getByField($customerRow['customer_id'], 'customer_id');
            //锁定
            $balanceRow = Service_CustomerBalance::getForUpdate( $balanceRow['cb_id'] );

            $balanceRow['cb_update_time'] = $date;
            $logArr = array();
            $releaseValue = $value = 0;
            foreach ($detailArr as $key => $feeArr) {
                $releaseValue = $feeArr['release_value'];
                //入款冻结税金
                $frozenTax = 0;
                $tax = 0;
                if( in_array($feeArr['cbl_type'], array('3','8'))) {
                    $rate = Service_CustomerProcess::getTaxRate( $customerCode );
                    if( $rate === false  )
                        throw new Exception('该客户未设置签约主体');
                    
                    $constant = Service_CustomerProcess::getConstant();

                    if( $rate > 0 ) {
						//批量重新计费的入款不需要做税金冻结
						if(strtolower($feeArr['application_code']) != 'readjustment' ){
							$tax = round( ( $feeArr['cbl_value'] / $constant) * $rate, 2 );
							$feeArr['cbl_value'] = $feeArr['cbl_value'] - $tax;
						}   
                    }
                }
                $value = $feeArr['cbl_value'];
                unset($feeArr['release_value']);
                $rateRow = self::changeCurrency($feeArr['cbl_value'], $feeArr['currency_code'], $currencyCode, $feeArr['currency_rate']);
                if (!is_array($rateRow)) {
                    $return['message'] = $rateRow;
                    return $return;
                }
                $price = $rateRow['value'];
                $taxTranslated = $rateRow['rate'] * $tax;
                $feeArr['currency_rate'] = $feeArr['currency_rate'] != '' ? $feeArr['currency_rate'] : $rateRow['rate'];
                $feeArr['cbl_transaction_value'] = $price;
                $feeArr['user_id'] = $feeArr['user_id'] != '' ? $feeArr['user_id'] : $userId;
                switch ($feeArr['cbl_type']) {
                    case 0:
                        $balanceRow['cb_value'] = $balanceRow['cb_value'] - $price;
                        $balanceRow['cb_hold_value'] = $balanceRow['cb_hold_value'] + $price;
                        $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                        $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                        $logArr[] = $feeArr;
                        break;
                    case 1:
                        $balanceRow['cb_value'] = $balanceRow['cb_value'] + $price;
                        $balanceRow['cb_hold_value'] = $balanceRow['cb_hold_value'] - $price;
                        $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                        $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                        $logArr[] = $feeArr;
                        break;
                    case 2:
                        //如果有解冻金额，先回退金额再扣款
                        if ($releaseValue > 0) {
                            $feeArr['cbl_type'] = 1;
                            $feeArr['cbl_value'] = $releaseValue;
                            //转币种
                            $releaseValue = sprintf("%.2f", $releaseValue * $rateRow['rate']);
                            $feeArr['cbl_current_value'] = $balanceRow['cb_value'] + $releaseValue;
                            $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'] - $releaseValue;
                            $logArr[] = $feeArr;
                        }
                        $feeArr['cbl_type'] = 2;
                        $feeArr['cbl_value'] = $value;
                        $balanceRow['cb_value'] = $balanceRow['cb_value'] + $releaseValue - $price;
                        $balanceRow['cb_hold_value'] = $balanceRow['cb_hold_value'] - $price;
                        $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                        $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                        $logArr[] = $feeArr;
                        break;
                    case 3:
                        $balanceRow['cb_value'] = $balanceRow['cb_value'] + $price;
                        //冻结税金，保宏签约的税率：6%，香港签约的税率：0%
                        $balanceRow['frozen_tax_amount'] = $taxTranslated + $balanceRow['frozen_tax_amount'];
                        $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                        $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                        $logArr[] = $feeArr;

                        //加上冻结税款日志
                        if( abs($tax) > 0 ) {
                            $feeArr['cbl_type'] = 5;
                            $feeArr['cbl_value'] = $tax;
                            $feeArr['cbl_transaction_value'] = $taxTranslated;
                            $feeArr['cbl_note'] = '客户充值，冻结税金';
                            $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                            $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                            $logArr[] = $feeArr;
                        }
                        break;
                    case 6://退还税金
                        $newTax = $balanceRow['frozen_tax_amount'] - $price;
                        if( $newTax < 0 ) {
                            throw new Exception( '可用税金不足' );
                        }
                        $feeArr['cbl_note'] = '申请退还税金';
                        $balanceRow['cb_value'] = $balanceRow['cb_value'] + $price;
                        $balanceRow['frozen_tax_amount'] = $newTax;
                        $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                        $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                        $logArr[] = $feeArr;

                        break;
                    case 8:
                        $balanceRow['cb_value'] = $balanceRow['cb_value'] + $price;
                        //冻结税金，保宏签约的税率：6%，香港签约的税率：0%
                        $balanceRow['frozen_tax_amount'] = $taxTranslated + $balanceRow['frozen_tax_amount'];
                        $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                        $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                        $logArr[] = $feeArr;
                    
                        //加上冻结税款日志
                        if( abs($tax) > 0 ) {
                            $feeArr['cbl_type'] = 5;
                            $feeArr['cbl_value'] = $tax;
                            $feeArr['cbl_transaction_value'] = $taxTranslated;
                            $feeArr['cbl_note'] = '客户充值，冻结税金';
                            $feeArr['cbl_current_value'] = $balanceRow['cb_value'];
                            $feeArr['cbl_current_hold_value'] = $balanceRow['cb_hold_value'];
                            $logArr[] = $feeArr;
                        }
                        break;
                    default:
                        break;

                }
            }
            $cbId = $balanceRow['cb_id'];
            unset($balanceRow['cb_id']);
            if (($balanceRow['cb_value'] == 0 ) && $opType == '0') {
                $return['message'] = 'insufficient fund.';
                return $return;
            }
            if (!Service_CustomerBalance::update($balanceRow, $cbId, 'cb_id')) {
                $return['message'] = 'Payment failure.';
                return $return;
            }
            $logObj = new Service_CustomerBalanceLog();
            foreach ($logArr as $feeLog) {
                $feeLog['customer_id'] = $customerRow['customer_id'];
                $feeLog['customer_code'] = $customerRow['customer_code'];
                $logObj->add($feeLog);
            }
            $return['state'] = 1;
            $return['message'] = 'Operation Successfully Completed';
            $return['data'] = array('customer_code' => $customerRow['customer_code'], 'cb_value' => $balanceRow['cb_value'], 'cb_hold_value' => $balanceRow['cb_hold_value'], 'currency_code' => $currencyCode);
        } catch (Exception $e) {
            $return['state'] = 0;
            $return['message'] = $e->getMessage();
        }
        return $return;
    }


    /**
     * 币种与金额转换
     * @param $value 转换金额
     * @param $orgCode 原始货币CODE
     * @param $disCode 目的货币CODE
     * @param null $orgRate 自定义原货币汇率
     * @return array/string
     */
    public static function changeCurrency($value, $orgCode, $disCode, $orgRate = 0)
    {

        $orgCode = strtoupper($orgCode);
        $disCode = strtoupper($disCode);
        $currencyRows = Service_Currency::getByCondition(array(), array('currency_code', 'currency_rate'));
        foreach ($currencyRows as $key => $val) {
            $currencyRows[$val['currency_code']] = $val['currency_rate'];
        }
        if ($orgRate != 0 && $orgRate != '') {
            $org_rate = $orgRate;
        } else {
            $org_rate = isset($currencyRows[$orgCode]) ? $currencyRows[$orgCode] : 0;
        }
        if ($orgCode == $disCode) {
            $result['value'] = $value;
            $result['currency_code'] = $disCode;
            $result['org_rate'] = $org_rate;
            $result['dis_rate'] = $org_rate;
            $result['rate'] = 1;
            return $result;
        }

        if (!isset($currencyRows[$orgCode]) || !isset($currencyRows[$disCode])) {
            $result = 'Can not find origin/destination currency code';
        } else {
            //取小数后两位，不作四舍五入
            $result['org_rate'] = $org_rate;
            $result['dis_rate'] = $currencyRows[$disCode];
            $result['rate'] = sprintf("%.5f", $org_rate / $currencyRows[$disCode]);
            $result['value'] = sprintf("%.2f", $value * $result['rate']);
            $result['currency_code'] = $disCode;
        }
        return $result;
    }

}