<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class PaymentService extends CI_Controller {

    public function __construct(){
        parent::__construct();
        bcscale(2);
        mb_regex_encoding("UTF-8");
        $this->load->helper('payment');
        $this->config->load('ipaylinks', true);
        $this->config->load('wxpay', true);
        $this->config->load('paypal', true);
        $this->load->library('ipaylinks_call');
        $this->load->library('wxpay_call');
        $this->load->library('alipay_call');
        $this->load->model('Online_payment_note_model', 'note_model');
        $this->load->model('Online_payment_account_model', 'account_model');
        $this->load->model('Group_model');
    }

    private $code_brandname = array(
        "15002" => "PayPal",
        "15010" => "PayPal",
        "15015" => "Alipay",
        "15016" => "WeChat",
        "15018" => "Credit Card-iPaylinks",
    );

    public function index()
    {
    }

    public function note_list()
    {
        $this->permission->is_admin(true);
        $data = array();
        $method = $this->input->get_post("method");
        $method = $method===false ? null : $method;
        $data['method_code'] = '';
        // $data["paytext"] = $this->payment_status();
        if (isset($this->code_brandname[$method])) {
            $data['method_code'] = $method;
            $data["method_name"] = $this->code_brandname[$method];
        }
        $data["keywords"] = $this->input->get_post("keywords");
        $data["date"] = $this->input->get_post("date");
        empty($data['date']) ? $data['date'] = date('Y-m-d') : false;
        if (!empty($data['keywords'])) {
            $data['notelist'] = $this->note_model->search_key($data['keywords']);
        } else {
            $search_date = $this->note_model->search_date($data['date'], $method);
            $unsend = $this->note_model->unsend_note(false, $method);
            $sendfail = $this->note_model->sendfail_note(false, $method);
            $closed = $this->note_model->closed_note($data['date'], 300, $method);
            $data['notelist'] = array_merge(array_merge($unsend, $sendfail), array_merge($search_date, $closed));
        }
        array_walk($data["notelist"], 'PaymentService::set_brandname');

        /**
         * 导出记录用的记录节点
         * TODO
         */
        // $data['record_flags'] = $this->note_model->list_export_record();

        $this->load->view("payment_list",$data);
        return;
    }

    public function note_faillist()
    {
        $this->permission->is_admin(true);
        $data = array();
        $data['date'] = date('Y-m-d');
        $data['method_code'] = '15016';
        $data["method_name"] = $this->code_brandname['15016'];
        $data['notelist'] = $this->note_model->sendfail_note(false);
        array_walk($data["notelist"], 'PaymentService::set_brandname');
        $this->load->view("payment_list",$data);
        return;
    }

    private $wxpay_app = array(
        "wx749246dd935ca07b" => "APP",
        "wx5d01021a6d515098" => "HLY", // "花梨鹰小程序", // 交行收款码
        "wxd6c8dd69af5128cd" => "", // "NATIVE",
        "wx7e605820faf98a05" => "Trippest-NATIVE",
        "0" => "unknown",
    );
    public function set_brandname(&$ele)
    {
        $ele->brand_name = "none";
        if ($this->code_brandname[$ele->OPN_accountMethod]) {
            $ele->brand_name = $this->code_brandname[$ele->OPN_accountMethod];
        }

        $raw = json_decode($ele->OPN_rawContent);
        $wx_app = isset($raw->app_id) ? $raw->app_id : '0';
        $wx_app = $wx_app!=='0' ? $wx_app : (isset($raw->appid) ? $raw->appid : '0');

        $ele->app_name = "";
        if ($this->wxpay_app[$wx_app]) {
            $ele->app_name = $this->wxpay_app[$wx_app];
        }
    }

    // https://www.mycht.cn/webht.php/apps/pay/paymentservice/test_new_function?coli_sn=WY211210012
    public function test_new_function() {
        echo 'test_new_function';
        $coli_sn = $this->input->get('coli_sn');
        $this->Group_model->update_ck_group_info($coli_sn);
        echo 'update_ck_group_info';
    }

    public function send_notify($opn_id=NULL, $old_ssje=NULL)
    {
        ignore_user_abort(true);
        $output = "处理交易记录:<br>";
        $data = array();
        $show_index = 0;
        //优先处理指定的交易号，用于修正交易号直接发送通知
        if ( ! empty($opn_id)) {
            $data['unsend_list'] = $this->note_model->get_note($opn_id);
        }
        // 待处理的
        if (empty($data['unsend_list'])) {
            $data['unsend_list'] = $this->note_model->unsend_note(20);
        }
        //没有未处理的数据再查找处理失败的数据
        if (empty($data['unsend_list'])) {
            $data['unsend_list'] = $this->note_model->sendfail_note(20);
        }
        // 开始处理
        foreach ($data['unsend_list'] as $key => $item) {
            // 只处理完成状态
            if (mb_strtolower($item->OPN_transactionResult) !== 'completed') {
                continue;
            }
            $is_refund = false;
            $ht_memo = '交易号(自动录入):' . $item->OPN_transactionId;
            if (mb_strtolower($item->OPN_noticeType) == 'refund') {
                $is_refund = true;
                $ht_memo = '(自动)退款号:' . $item->OPN_transactionId . "\n. ";
                // todo:
                // $ht_memo .= '原交易号:' . $parent_dealId;
                // continue ;
            }

            // 提取订单号
            $orderid_info = analysis_orderid($item->OPN_orderId); // 先用已设置过的
            if (empty($orderid_info)) {
                $orderid_info = $this->method_analysis_orderid($item);
                if (empty($orderid_info)) {
                    $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'sendfail');
                    continue;
                }
            }
            $orderid_info = json_decode($orderid_info);
            // TODO Trippest的订单号要特别查询
            // 填入提取到的订单号
            $this->note_model->set_invoice($item->OPN_SN, $orderid_info->orderid . '_' . $orderid_info->ordertype);

            $send_email = true;
            // APP自动出票的收款 跳过
            if ($orderid_info->ordertype === 'A' && $item->OPN_noticeType === 'pay') {
                $send_email = false;
                // $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'closed');
                // continue;
            }

            // 开始查找订单和录入
            $handpick = empty($opn_id) ? false : true;
            $advisor_info = $this->account_model->get_order($orderid_info->orderid, true, $orderid_info->ordertype, $handpick);
            // $ssje = $this->account_model->get_ssje($item->OPN_orderAmount, mb_strtoupper($item->OPN_currency), $item->OPN_accountMethod);
            $ssje = $item->OPN_entryAmountCNY;
            $ssje = $old_ssje===NULL ? $ssje : $old_ssje;
            $currencyCode = str_replace("CNY", "RMB", trim(mb_strtoupper($item->OPN_currency)));
            $currencyCode = mb_strtoupper(trim($currencyCode));

            //根据订单号查找外联信息, 从临时表
            $advisor_info_from_tmp = $this->account_model->get_order($orderid_info->orderid, false, 'M', $handpick);
            /**
             * 传统订单, 网站支付
             * @author LYT
             */
            if (empty($advisor_info) && ! empty($advisor_info_from_tmp) && $orderid_info->ordertype == 'T') {
                // $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'closed');
                $this->note_model->set_invoice($item->OPN_SN, $advisor_info_from_tmp->COLI_ID . '_' . $orderid_info->ordertype);
                continue;
            }

            if ( empty($advisor_info)) {
                // record fail
                $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'sendfail');
                continue;
            }
            $COLI_SN = isset($advisor_info->COLI_SN) ? $advisor_info->COLI_SN : 0;
            $this->Group_model->update_ck_group_info($COLI_SN);
            $update_note_column = array();
            if ($advisor_info->order_type == 0) {
                /* 商务订单 */
                // todo: 检测收/退款是否存在
                if (substr($advisor_info->COLI_WebCode, 0, 6) == 'CHTAPP'  && strstr($advisor_info->COLI_WebCode, "-") !== '-biz') {
                    /* APP */
                    $this->account_model->add_account_info_forAPP(
                        $COLI_SN,
                        $item->OPN_accountMethod,
                        $advisor_info->COLI_ID,
                        $item->OPN_orderAmount,
                        $item->OPN_completeTime,
                        $currencyCode,
                        $ssje,
                        $item->OPN_completeTime,
                        $item->OPN_completeTime,
                        $item->OPN_completeTime,
                        $item->OPN_payerName,
                        $item->OPN_payerEmail,
                        $item->OPN_transactionId,
                        $ht_memo
                    );
                    if ($advisor_info->COLI_WebCode == 'CHTAPP' && $advisor_info->COLI_State == 11
                        && false===$is_refund) {
                        //只修改APP组的订单状态，并且订单进度是我的订单
                        $this->account_model->update_biz_coli_state($COLI_SN, 8); //把订单状态改为已付款
                        $this->account_model->insert_biz_order_log($COLI_SN, 'BS8');
                    }
                } else {
                    /* 其他商务订单 */
                    // 第一次录入收款记录时变更状态,记录日志
                    if (false == $this->account_model->if_biz_gai_exists($item->OPN_transactionId)
                        && false===$is_refund
                    ) {
                        $this->account_model->update_biz_coli_state($COLI_SN, 13);
                        $this->account_model->insert_biz_order_log($COLI_SN, 'BS13');
                    } else {
                        $this->account_model->insert_biz_order_log($COLI_SN, 'Refunded');
                    }
                    $this->account_model->add_account_info(
                        $COLI_SN,
                        $item->OPN_accountMethod,
                        $advisor_info->COLI_ID,
                        $item->OPN_orderAmount,
                        $item->OPN_completeTime,
                        $currencyCode,
                        $ssje,
                        $item->OPN_completeTime,
                        $item->OPN_completeTime,
                        $item->OPN_completeTime,
                        $item->OPN_payerName,
                        $item->OPN_payerEmail,
                        $item->OPN_transactionId,
                        $ht_memo
                    );
                    // 更新订单主表付款方式,防止没访问thankyou-train.asp
                    $this->account_model->update_paymanner($COLI_SN, $item->OPN_accountMethod);
                }
                // 更新note
                $update_note_column['OPN_accountType'] = 'B';
                $update_note_column['OPN_accountStatus'] = 'recorded';
                $update_note_column['OPN_accountTime'] = date('Y-m-d H:i:s');
            } elseif ($advisor_info->order_type == 1) {
                /* 传统 */
                $gai_sn = $this->account_model->add_tour_account_info(
                    $COLI_SN,
                    $item->OPN_accountMethod,
                    $item->OPN_orderAmount,
                    $item->OPN_completeTime,
                    $currencyCode,
                    $ssje,
                    $item->OPN_completeTime,
                    $item->OPN_completeTime,
                    $item->OPN_completeTime,
                    $item->OPN_payerName,
                    $item->OPN_payerEmail,
                    $item->OPN_transactionId,
                    $ht_memo
                );
                if ($is_refund === false) {
                    //添加汉特的订单提醒
                    $this->account_model->update_coli_introduction($COLI_SN, '已支付 ' . $currencyCode . $item->OPN_orderAmount);
                    // 收款:添加HT任务
                    $this->account_model->exec_addToTask($gai_sn);
                }
                // 更新note
                $update_note_column['OPN_accountType'] = 'B';
                $update_note_column['OPN_accountStatus'] = 'recorded';
                $update_note_column['OPN_accountTime'] = date('Y-m-d H:i:s');
            }
            // 更新note
            if ( ! empty($update_note_column)) {
                $where = " OPN_SN=" . $item->OPN_SN;
                $this->note_model->update_note($where, $update_note_column);
            }
            if ($send_email===false) {
                $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'closed');
                continue; // 这里不跳出, 退款后续需要检测是否发送财务
            }
            // 邮件外联
            $opi_email = !empty($advisor_info->OPI_Email) ? $advisor_info->OPI_Email : '';
            $opi_firstname = !empty($advisor_info->OPI_FirstName) ? $advisor_info->OPI_FirstName : !empty($advisor_info->OPI_Name) ? $advisor_info->OPI_Name : '';
            if ($opi_email===''
                && in_array(strtoupper($advisor_info->COLI_WebCode), array('CHTAPP-JA', 'JP'))
            ) {
                $opi_email = 'contact@arachina.com';
                $opi_firstname = 'contact@arachina.com';
            }

            /**
             * 已经记录的再次遇到就忽略了
             * @author LYT
             */
            if (empty($opi_email) && $item->OPN_accountStatus === 'recorded') {
                $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send');
                continue;
            }

            //没有外联信息表示订单未分配
            if (empty($opi_email) || empty($opi_firstname)) {
                $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'sendfail');
                continue;
            }
            //添加邮件发送记录
            //给外联发送通知邮件
            if ($send_email===true && $handpick===false && $item->OPN_noticeSendStatus !== 'send' && substr($item->OPN_noticeSendStatus, 0, 5) !== 'send-') {
                $fromName = !empty($item->OPN_payerName) ? $item->OPN_payerName : '';
                $fromEmail = !empty($item->OPN_payerEmail) ? $item->OPN_payerEmail : '';
                $toName = !empty($opi_firstname) ? $opi_firstname : '';
                $toEmail = !empty($opi_email) ? $opi_email : '';
                $subject = $orderid_info->orderid . '_' . $orderid_info->ordertype . ' / ' . $item->OPN_orderAmount . $item->OPN_currency . ' / ' . $fromName;
                $body = $this->load->view('mail_advisor', $item, true); //$item->pn_memo;
                $M_RelatedInfo = $item->OPN_SN;
                $M_AddTime = $item->OPN_completeTime;
                $M_State = 0;
                $this->account_model->save_automail($fromName, $fromEmail, $toName, $toEmail, $subject, $body, $M_RelatedInfo, $M_State, $M_AddTime, 'payment note', 'payment note');
                //添加邮件发送记录 end
                $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send');
            }
            // 2. 给客人发邮件,通知账单
            // todo:iPaylinks需要发收款, 退款发所有
            // 3. 更新是否发送财务
            if($is_refund === true ) {
                $this->send_refund($send_email, $item, $orderid_info, $advisor_info);
            }

            //显示处理记录
            if (empty($opn_id)) {
                $output .= (++$show_index) . ' ' . $item->OPN_transactionId . '<br/>';
            }

        }
        if (empty($opn_id)) {
            echo $output;
        }
        return $output;
        // return $this->output->set_content_type('application/json')->set_output(json_encode($data));
    }

    public function send_refund($send_email, $item, $orderid_info, $advisor_info)
    {
        // 发送客人
        if ($send_email===true
            && $item->OPN_noticeSendStatus !== 'send' && substr($item->OPN_noticeSendStatus, 0, 5) !== 'send-'
        ) {
            // 客人邮件中的外联落款
            // $web_code = 'cht'; // 默认cht
            $web_lgc = 1;
            $web_code = strtolower($advisor_info->COLI_WebCode);
            $site_info = $this->config->item('site');
            if (isset($site_info[$web_code])) {
                $site_info = $site_info[$web_code];
                $item->site = $site_info['site_url'];
                $web_lgc =  $site_info['site_lgc'];
            }
            $advisor_detail = $this->account_model->get_advisor_detail($advisor_info->COLI_SN, $advisor_info->OPI_SN, $web_lgc);
            $item->advisor_detail = $advisor_detail;
            $customer_detail = $this->account_model->get_customer_detail($advisor_info->COLI_SN, $orderid_info->ordertype);
            $c_fromName = $advisor_detail->fullname;
            $opi_email_list = explode(";", $advisor_detail->email); // 解析外联的邮件
            $c_fromEmail = trim($opi_email_list[0]);
            $c_toName = $customer_detail->fullname;
            $c_toEmail = $customer_detail->email;
            $c_subject = mb_strtoupper($item->OPN_currency) . " " . str_replace('-', '', $item->OPN_orderAmount) . " Refunded to your account, booking number " . $item->OPN_orderId;
            // 修改一些字段名, 为了和Alipay等用同一个邮件模板
            $item->payer = $customer_detail->fullname;
            $item->payer_email = $customer_detail->email;
            $item->total_amount = $item->OPN_orderAmount;
            $item->payment_date = $item->OPN_completeTime;
            $item->payment_status = "Refunfed";
            $item->currency = mb_strtoupper($item->OPN_currency);
            $item->invoice = $item->OPN_orderId;
            $c_body = $this->load->view('refund_buyer', $item, true);
            $c_M_RelatedInfo = $item->OPN_SN;
            $c_M_AddTime = $item->OPN_completeTime;
            $c_M_State = 0;
            $this->account_model->save_automail(
                $c_fromName,
                $c_fromEmail,
                $c_toName,
                $c_toEmail,
                $c_subject,
                $c_body,
                $c_M_RelatedInfo,
                $c_M_State,
                $c_M_AddTime,
                'ChinaHighlights refund receipt',
                'payment note');
            $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send-customer');
        }
        // 更新是否需要发送财务
        $refund_finance_day = 20;
        $now_day = date('d');
        $late_entry_date_set = $now_day<$refund_finance_day ? date('Y-m-01', strtotime("-1 month")) : date('Y-m-01');
        if ($this->account_model->if_finance_done($advisor_info->COLI_GRI_SN, $late_entry_date_set) === true) {
            $this->note_model->update_send($item->OPN_SN, $item->OPN_transactionId, 'send-to-finance');
        }
        return;
    }

    /** 支付方式参数对应的配置文件名 */
    /** @Deprecated */
    public function method_name($name)
    {
        $config_name = 'paypal';
        switch ($name) {
            case 'paypal':
                $config_name = 'paypal';
                break;
            case 'weixin':
                $config_name = 'wxpay';
                break;
            case 'ipaylinks':
                $config_name = 'iPayLinks';
                break;
            case 'alipay':
                $config_name = 'alipay';
                break;

            default:
                # code...
                break;
        }
        return $config_name;
    }

    private function method_analysis_orderid($opn_obj)
    {
        // $orderid_info = $this->method_analysis_orderid($item->OPN_accountMethod, $item->OPN_rawContent);
        $content_obj = json_decode($opn_obj->OPN_rawContent);
        $orderid_info = array();
        switch (strval($opn_obj->OPN_accountMethod)) {
            case '15002':
            case '15010': // paypal
                $orderid_info = analysis_orderid($content_obj->invoice);
                empty($orderid_info) ? $orderid_info = analysis_orderid($content_obj->transaction_subject) : NULL;
                empty($orderid_info) ? $orderid_info = analysis_orderid($content_obj->custom) : NULL;
                empty($orderid_info) ? $orderid_info = analysis_orderid($content_obj->item_name) : NULL;
                empty($orderid_info) ? $orderid_info = analysis_orderid($content_obj->item_name1) : NULL;
                empty($orderid_info) ? $orderid_info = analysis_orderid($content_obj->item_number) : NULL;
                empty($orderid_info) ? $orderid_info = analysis_orderid($content_obj->item_number1) : NULL;
                break;

            case '15016': // wxpay
                $orderid_info = analysis_orderid($content_obj->out_trade_no);
                if (empty($orderid_info) && $opn_obj->OPN_fundSource==='cht' && $content_obj->trade_type==='APP') {
                    $orderid_info = analysis_orderid($content_obj->out_trade_no . "_A");
                }
                break;
            // TODO
            case '15018': // iPaylinks
                break;
            case '15015': // alipay
                break;

            default:
                # code...
                break;
        }
        return $orderid_info;
    }

    public function convert_send_status()
    {
        # code...
    }

    public function gai_modal($pn_id = null, $neworder=null)
    {
        $this->permission->is_admin(true);
        $data = array();
        $note = $this->note_model->get_note($pn_id);
        $data['note'] = $note[0];
        $data['order_info'] = NULL;
        $pn_invoice = $data['note']->OPN_orderId ? $data['note']->OPN_orderId : $data['note']->OPN_rawOrderId;
        $pn_txn_id = $data['note']->OPN_transactionId;
        $orderid_info = analysis_orderid($pn_invoice);
        if (!empty($orderid_info)) {
            $orderid_info = json_decode($orderid_info);
            $data['order_info'] = $this->account_model->get_order($orderid_info->orderid, true, $orderid_info->ordertype, true);
            if ($orderid_info->ordertype === 'T') {
                $data['gai_info'] = $this->account_model->get_money_t($pn_txn_id);
            } elseif ($orderid_info->ordertype === 'B' || $orderid_info->ordertype === 'TP'
                || $orderid_info->ordertype === 'A'
            ) {
                $data['gai_info'] = $this->account_model->get_money_b($pn_txn_id);
            }
        }
        $data['old_order'] = $pn_invoice;
        $data['new_order'] = $neworder;
        if ($neworder !== null ) {
            $neworder_id = analysis_orderid($neworder);
            $neworder_id = json_decode($neworder_id);
            if ( ! empty($neworder_id)) {
                $data['order_info'] = $this->account_model->get_order($neworder_id->orderid, true, $neworder_id->ordertype, true);
            }
        }
        $order_sn = empty($data['order_info']) ? 0 : $data['order_info']->COLI_SN;
        $data['group_accout_info'] =
            $this->account_model->get_group_accout_info($order_sn, $pn_txn_id);
        echo json_encode($this->load->view('payment_gai_setting', $data, true));
    }

    public function gai_modal_save()
    {
        $data = array();
        $old_ssje = NULL;
        $pn_txn_id = $this->input->post('pn_txn_id');
        $pn_id = $this->input->post('pn_id');
        $neworder = $this->input->post('pn_invoice');

        $note = $this->note_model->get_note($pn_id);
        $data['note'] = $note[0];
        $orderid_info = analysis_orderid($data['note']->OPN_orderId);
        if (!empty($orderid_info)) {
            $orderid_info = json_decode($orderid_info);
            if ($orderid_info->ordertype === 'T') {
                $data['gai_info'] = $this->account_model->get_money_t($pn_txn_id);
                if ( ! empty($data['gai_info'])) {
                    $old_ssje = $data['gai_info'][0]->GAI_SSJE;
                    $this->account_model->delete_money_t($pn_txn_id);
                }
            } elseif ($orderid_info->ordertype === 'B' || $orderid_info->ordertype === 'TP'
                || $orderid_info->ordertype === 'A'
            ) {
                $data['gai_info'] = $this->account_model->get_money_b($pn_txn_id);
                if ( ! empty($data['gai_info'])) {
                    $old_ssje = $data['gai_info'][0]->GAI_SSJE;
                    $this->account_model->delete_money_b($pn_txn_id);
                }
            }
        }

        if (!empty($pn_txn_id) && !empty($neworder)) {
            $orderid_info = analysis_orderid($neworder);
            if (!empty($orderid_info)) {
                $orderid_info = json_decode($orderid_info);
                $advisor_info = $this->account_model->get_order($orderid_info->orderid, false, $orderid_info->ordertype, true);
                if (!empty($advisor_info)) {
                    $this->note_model->set_invoice($data['note']->OPN_SN, $neworder);
                    $this->send_notify($data['note']->OPN_SN, $old_ssje);
                    echo json_encode('修改成功！');
                    return true;
                }
            }
        }
        echo json_encode('没找到数据！');
        return;
    }

    public function close_gai($opn_id)
    {
        $data = array();
        $data['note'] = $this->note_model->get_note($opn_id);
        if (!empty($data['note'])) {
            $this->note_model->update_send($opn_id, $data['note'][0]->OPN_transactionId, 'closed');
            echo json_encode('该收款记录已经忽略！');
            return true;
        }
        echo json_encode('没找到数据！');
        return;
    }

    /*!
     * 发送状态是send-to-finance的记录
     * refund-imported
     * @date   2019-05-15
     */
    public function refund_finance_notify()
    {
        $all_list = $this->account_model->get_refund_imported();
        if (empty($all_list)) {
            echo "No refund record.";
            return false;
        }
        $this->load->library('PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->setActiveSheetIndex(0);
        //set width
        $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(5);
        $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(15); // 部门
        $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(30); // 团号
        $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(15); // 金额
        $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(15); // 币种
        $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(15); // 人民币
        $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(20); // 付款人
        $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(30); // 邮箱
        $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(20); // 交易号
        $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(20); // 时间
        $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(20); // 交易平台
        // 对齐
        $objPHPExcel->getActiveSheet()->getStyle('D')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
        $objPHPExcel->getActiveSheet()->getStyle('F')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
        // 表标题行
        $objPHPExcel->getActiveSheet()
                    ->SetCellValue('A1', '#')
                    ->SetCellValue('B1', '部门')
                    ->SetCellValue('C1', '团号')
                    ->SetCellValue('D1', '金额')
                    ->SetCellValue('E1', '币种')
                    ->SetCellValue('F1', '人民币')
                    ->SetCellValue('G1', '付款人')
                    ->SetCellValue('H1', '邮箱')
                    ->SetCellValue('I1', '交易号')
                    ->SetCellValue('J1', '时间')
                    ->SetCellValue('K1', '交易平台')
                    ;
        $currency_sum = array();
        bcscale(2);
        $rowCount = 2;
        foreach ($all_list as $key => $row) {
            $objPHPExcel->getActiveSheet()
                        ->SetCellValue('A'.$rowCount, ($rowCount-1))
                        ->SetCellValue('B'.$rowCount, $row['department'])
                        ->setCellValueExplicit('C'.$rowCount, $row['gri_name'], PHPExcel_Cell_DataType::TYPE_STRING)
                        ->setCellValueExplicit('D'.$rowCount, number_format($row['amount'], 2, ".", ""),PHPExcel_Cell_DataType::TYPE_STRING)
                        ->SetCellValue('E'.$rowCount, trim($row['currency']))
                        ->setCellValueExplicit('F'.$rowCount, $row['amount_CNY'], PHPExcel_Cell_DataType::TYPE_STRING)
                        ->SetCellValue('G'.$rowCount, $row['payer'])
                        ->SetCellValue('H'.$rowCount, $row['payer_email'])
                        ->setCellValueExplicit('I'.$rowCount, $row['transaction_id'], PHPExcel_Cell_DataType::TYPE_STRING)
                        ->SetCellValue('J'.$rowCount, $row['payment_date'])
                        ->SetCellValue('K'.$rowCount, $row['payment_type'])
                        ;
            $rowCount++;
        }
        $time_set = date('Y-m-d_H_i_s');
        $filename = "refund_imported_" . $time_set;
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save(FCPATH . "download_statement/refund/" . $filename . ".xls");
        if (file_exists(FCPATH . "download_statement/refund/" . $filename . ".xls")) {
            // 保存成功:更新标记,邮件
            foreach ($all_list as $ka => $va) {
                $this->account_model->update_send_fiance($va['note_sn'], $va['payment_type']);
            }
            $fromName = 'refund imported';
            $fromEmail = '';
            $toName = 'huangyi'; // 'fgy';
            $toEmail = 'hyi@hainatravel.com'; // 'fgy@hainatravel.com';
            $subject = $filename;
            $body = "导入账单后有退款, 已汇总到文件. <br>文件生成日期:". date("Y-m-d H:i"). ". <br>下载链接: https://www.mycht.cn/download_statement/refund/" . $filename . ".xls";
            $M_AddTime = $time_set;
            $M_State = 0;
            $this->account_model->save_automail($fromName, $fromEmail, $toName, $toEmail, $subject, $body, 0, $M_State, $M_AddTime, 'refund imported', 'refund imported');
        }
        return false;
    }

    public function ipalinks_settlement($year, $month, $day="01")
    {
        set_time_limit(0);
        ignore_user_abort(true);
        $fun_version = $this->input->get_post('fun');

        $target_folder = "ipaylinks-" . $year;
        $target_file = $year . "-" . $month;
        // $target_file .= ($day===null) ? null : ("-" . $day);
        if ($day !== null) {
            $target_folder .= "\\" . $month;
            $target_file = $year . $month . $day . "_transaction";
        }
        $statement_folder = FCPATH.'download_statement\settlement_files\\' . $target_folder;
        if ( ! is_dir($statement_folder)) {
            echo "read folder failed";
            return;
        }
        $files = array_values(array_diff(scandir($statement_folder), array('.', '..')));
        if (empty($files)) {
            echo "none excel.";
            return;
        }
        $file_path_output = "";
        foreach ($files as $k => $fe) {
            if ( ! in_array(strrchr($fe, '.'), array(".xlsx", ".xls"))) {
                continue;
            }
            if (stripos($fe, $target_file)===false) {
                continue;
            }
            $file_path = $statement_folder . '\\' . $fe;
            if ( ! file_exists($file_path)) {
                continue;
            }
            if ($target_file==='2019-09') { // 2019.09.10 切换清算账单, 此处特殊处理
                $settlement_record = $this->ipaylinks_call->read_excel_old($file_path);
                $update_cnt = $this->ipaylinks_call->save_excel_old($settlement_record);
                $settlement_record2 = $this->ipaylinks_call->read_excel_new($file_path,1);
                $update_cnt2 = $this->ipaylinks_call->save_excel_new($settlement_record2);
                $update_cnt += $update_cnt2;
            } else if ($fun_version==='old') {
                $settlement_record = $this->ipaylinks_call->read_excel_old($file_path);
                $update_cnt = $this->ipaylinks_call->save_excel_old($settlement_record);
            } else {
                $settlement_record = $this->ipaylinks_call->read_excel_new($file_path);
                $update_cnt = $this->ipaylinks_call->save_excel_new($settlement_record);
            }
            $file_path_output .= "\r\n" . $file_path;
            if ($k > 0) {
                break;
            }
        }
        $result = "Store $update_cnt records;" . $file_path_output;
        log_message('error', $result);
        echo $result;
        return;
    }

    public function wechat_settlement($year, $month)
    {
        set_time_limit(0);
        ignore_user_abort(true);

        $target_folder = "wechat-" . $year;
        $target_file = $year . "." . $month;
        // $target_file .= ($day===null) ? null : ("-" . $day);
        $statement_folder = FCPATH.'download_statement\settlement_files\\' . $target_folder;
        if ( ! is_dir($statement_folder)) {
            echo "read folder failed";
            return;
        }
        $files = array_values(array_diff(scandir($statement_folder), array('.', '..')));
        if (empty($files)) {
            echo "none excel.";
            return;
        }
        $file_path_output = "";
        foreach ($files as $k => $fe) {
            if ( ! in_array(strrchr($fe, '.'), array(".xlsx", ".xls"))) {
                continue;
            }
            if (stripos($fe, $target_file)===false) {
                continue;
            }
            $file_path = $statement_folder . '\\' . $fe;
            if ( ! file_exists($file_path)) {
                continue;
            }
            $settlement_record = $this->wxpay_call->read_settlement_excel($file_path);
            $update_cnt = $this->wxpay_call->save_settlement_excel($settlement_record);
            // log_message('error','0' . PHP_EOL . var_export($settlement_record[0], 1));
            // $update_cnt = 0;
            $file_path_output .= "\r\n" . $file_path;
            if ($k > 0) {
                break;
            }
        }
        $result = "Store $update_cnt records;" . $file_path_output;
        log_message('error', $result);
        echo $result;
        return;
    }

    public function alipay_settlement($year, $month)
    {
        set_time_limit(0);
        ignore_user_abort(true);

        $target_folder = "alipay-" . $year;
        $target_file = $year . "." . $month;
        // $target_file .= ($day===null) ? null : ("-" . $day);
        $statement_folder = FCPATH.'download_statement\settlement_files\\' . $target_folder;
        if ( ! is_dir($statement_folder)) {
            echo "read folder failed";
            return;
        }
        $files = array_values(array_diff(scandir($statement_folder), array('.', '..')));
        if (empty($files)) {
            echo "none excel.";
            return;
        }
        $file_path_output = "";
        foreach ($files as $k => $fe) {
            if ( ! in_array(strrchr($fe, '.'), array(".xlsx", ".xls"))) {
                continue;
            }
            if (stripos($fe, $target_file)===false) {
                continue;
            }
            $file_path = $statement_folder . '\\' . $fe;
            if ( ! file_exists($file_path)) {
                continue;
            }
            $settlement_record = $this->alipay_call->read_settlement_excel($file_path);
            $update_cnt = $this->alipay_call->save_settlement_excel($settlement_record);
            // log_message('error','0' . PHP_EOL . var_export($settlement_record[0], 1));
            // $update_cnt = 0;
            $file_path_output .= "\r\n" . $file_path;
            if ($k > 0) {
                break;
            }
        }
        $result = "Store $update_cnt records;" . $file_path_output;
        log_message('error', $result);
        echo $result;
        return;
    }

    public function income_statistics()
    {
        $this->permission->is_admin(true);

        $date_range = $this->input->post("date_range");
        preg_match_all('/\d{4}\-\d{2}\-\d{2}/', $date_range, $date_range_arr);
        if (empty($date_range_arr[0])) {
            // $data['from_date'] = date("Y-m-d", strtotime("-8 days"));
            // $data['to_date'] = date("Y-m-d", strtotime("-1 days"));
            $data['from_date'] = date("Y-m-01", strtotime("-1 month"));
            $data['to_date'] = date("Y-m-01 23:59:59");
        } else {
            $data['from_date'] = $date_range_arr[0][0];
            $data['to_date'] =$date_range_arr[0][1] . " 23:59:59";
            if ($data['to_date'] == null) {
                $data['to_date'] = date("Y-m-d  23:59:59", strtotime("+1 month", strtotime($data['from_date']))-1);
            }
        }

        $data['at_year'] = date('Y-01-01', strtotime($data['to_date']));
        $data['day_cnt'] = calc_day_cnt($data['from_date'], $data['to_date'])+1;
        $data['from_date_quarter'] = date('Y-m-d', strtotime("-" . $data['day_cnt'] . " days ", strtotime($data['from_date'])));
        $data['to_date_quarter'] = date('Y-m-d 23:59:59', strtotime("-" . $data['day_cnt'] . " days ", strtotime($data['to_date'])));
        $data['from_date_year'] = date('Y-m-d', strtotime("-1 year ", strtotime($data['from_date'])));
        $data['to_date_year'] = date('Y-m-d 23:59:59', strtotime("-1 year ", strtotime($data['to_date'])));

        $data['data']['pay'] = $this->note_model->total_by_method('pay',
            $data['from_date'], $data['to_date'],
            $data['from_date_quarter'], $data['to_date_quarter'],
            $data['from_date_year'], $data['to_date_year'],
            $data['at_year']
        );

        $data['data']['refund'] = $this->note_model->total_by_method('refund',
            $data['from_date'], $data['to_date'],
            $data['from_date_quarter'], $data['to_date_quarter'],
            $data['from_date_year'], $data['to_date_year'],
            $data['at_year']
        );
        array_walk($data['data']['pay'], 'PaymentService::set_brandname');
        array_walk($data['data']['refund'], 'PaymentService::set_brandname');
        bcscale(4);
        $data['data']['income'] = array();
        foreach ($data['data']['pay'] as $key => $pay) {
            $income_tmp = new stdClass();
            foreach ($data['data']['refund'] as $key => $refund) {
                if ($pay->OPN_accountMethod === $refund->OPN_accountMethod) {
                    $income_tmp->OPN_accountMethod = $pay->OPN_accountMethod;
                    $income_tmp->brand_name = $pay->brand_name;
                    $income_tmp->method_total_income = bcadd($pay->method_total_income, $refund->method_total_income);
                    $income_tmp->method_total_income_cmp = bcadd($pay->method_total_income_cmp, $refund->method_total_income_cmp);
                    $income_tmp->year_method_total_income = bcadd($pay->year_method_total_income, $refund->year_method_total_income);
                    $income_tmp->this_year_method_total_income = bcadd($pay->this_year_method_total_income, $refund->this_year_method_total_income);
                    $income_tmp->quarter_rate = $income_tmp->method_total_income_cmp==0 ? 100 :
                        bcdiv(
                            bcsub($income_tmp->method_total_income, $income_tmp->method_total_income_cmp),
                            ($income_tmp->method_total_income_cmp)
                        )*100;
                    $income_tmp->year_rate = $income_tmp->year_method_total_income==0 ? 100 :
                        bcdiv(
                            bcsub($income_tmp->method_total_income, $income_tmp->year_method_total_income),
                            ($income_tmp->year_method_total_income)
                        )*100;
                    $data['data']['income'][] = $income_tmp;
                }
            }
        }
        $this->load->view('income', $data, FALSE);
        return;
    }

}

