<?php
/**
 * @link      http://www.u-bo.com
 * @copyright 南京友博网络科技有限公司 
 * @license   http://www.u-bo.com/license/
 */

namespace home\modules\reimbursement\models;

use Yii;
use yii\helpers\Url;
use yii\db\ActiveRecord;
use qcbase\models\Auth;
use qcbase\models\UserDepartment;
use home\modules\reimbursement\models\ApplicationCategory;
use home\models\Announcement;
use yii\base\ErrorException;
use common\models\PermissionScope;

/**
 * 报销申请单表 ({%receivable_application})
 *
 * @property integer $appli_id  (申请单ID)
 * @property string $name  (申请单名称)
 * @property string $link_type  (关联类型)
 * @property string $link_id  (关联ID)
 * @property smallint $category_id  (报销类别ID (关联qc_application_category表)
 * @property decimal $money  (金额)
 * @property string $verify_ids (审核人 关联表qc_user)
 * @property smallint $isused (是否使用)
 * @property string $remark  (备注)
 * @property integer $create_time  (创建时间)
 * @property smallint $isverify  (审核状态   0待审核   1通过   2否决)
 * @property smallint $status  (状态  99逻辑删除)
 * @property integer $user_id  (创建人ID)
 * @property string $ip  (创建人IP)
 *
 * @author Strief http://blog.u-bo.com
 * @since 0.1
 */
class Application extends ActiveRecord
{
    const ISVERIFY_WAIT = 0; //审核状态:待审核
    const ISVERIFY_ENABLE = 1; //审核状态:通过
    const ISVERIFY_DISABLE = 2; ///审核状态:否决
    const ISUSED_ENABLE = 0; //使用状态：未使用
    const ISUSED_DISABLE = 1; //使用状态：已使用

    public $link_name;
    public $category_name;
    public $verify_names;
    public $verify_status;
    public $verify_remark;
    public $verify_id;
    public $isShow = true;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%reimbursement_application}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['name', 'link_type', 'link_id', 'money', 'verify_names'], 'required'],
            [['money'], 'number', 'max' => 99999999.99],
            [['isverify', 'status', 'user_id', 'isused', 'category_id'], 'integer'],
            [['name'], 'string', 'max' => 50],
            [['remark', 'verify_ids'], 'string', 'max' => 255],
            [['ip'], 'string', 'max' => 15]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'appli_id' => '申请单ID',
            'name' => '用途',
            'link_type' => '关联类型',
            'link_id' => '关联ID',
            'category_id' => '类别',
            'money' => '金额(元)',
            'verify_ids' => '审核人',
            'isused' => '绑定',
            'remark' => '备注',
            'create_time' => '创建时间',
            'isverify' => '审核状态',
            'status' => '状态',
            'user_id' => '创建人ID',
            'ip' => '创建人Ip',
            'verify_names' => '审核人',
        ];
    }

    /**
     * 公共搜索所需信息
     * 
     * 这里返回公共搜索的信息，我们希望所有的搜索走统一的配置
     * 返回值里的键名为keywords的数组为搜索里关键字搜索所支持的字段
     * 返回值里的键名为status的数组为搜索里状态搜索所支持的字段
     */
    public function search()
    {
        return [
            'keywords' => [
                'name' => '用途',
            ],
            'isused' => [
                self::ISUSED_ENABLE => '未使用',
                self::ISUSED_DISABLE => '已使用',
            ],
            'status' => self::getStatusList(),
        ];
    }

    /**
     * 关联获取报销类别表信息
     */
    public function getCategory()
    {
        return $this->hasOne(ApplicationCategory::className(), ['cat_id' => 'category_id']);
    }

    /**
     * 不同角色进入时的列表排序(搭配SORT_ASC使用)
     * 
     * @param string $type 角色类型('appli'报销人 'verify'审核人)
     * @param string $pk 排序字段
     * 
     * @return string 排序格式
     *
     * 使用方法
     * ~~
     * $query->orderBy([
     *      Application::isverifyOrderBy('appli') => SORT_ASC,
     *      'appli_id' => SORT_DESC,
     *      'create_time' => SORT_DESC,
     *      ]);
     * ~~
     */
    public static function isverifyOrderBy($type = 'appli', $pk = 'isverify')
    {
        $appliConfig = Yii::$app->cache->get('application_config');
        if ($type == 'appli') {
            $reimOrder = (isset($appliConfig['application_reim_order'])) ? $appliConfig['application_reim_order'] : [self::ISVERIFY_DISABLE, self::ISVERIFY_WAIT, self::ISVERIFY_ENABLE];
            //对于报销数据提交人，按被否决、待审核、审核通过的优先级排序
            //return "INSTR('" . self::ISVERIFY_DISABLE . "," . self::ISVERIFY_WAIT . "," . self::ISVERIFY_ENABLE . "', " . $pk . ")";
            return "INSTR('" . implode(',', $reimOrder) . "', " . $pk . ")";
        } else {
            $reimOrder = (isset($appliConfig['application_verify_order'])) ? $appliConfig['application_verify_order'] : [self::ISVERIFY_WAIT, self::ISVERIFY_DISABLE, self::ISVERIFY_ENABLE];
            //对于审核人操作，按待审核、被否决、审核通过的优先级排序
            //return "INSTR('" . self::ISVERIFY_WAIT . "," . self::ISVERIFY_DISABLE . "," . self::ISVERIFY_ENABLE . "', " . $pk . ")";
            return "INSTR('" . implode(',', $reimOrder) . "', " . $pk . ")";
        }
    }

    /**
     * 返回状态列表 
     */
    public static function getStatusList()
    {
        return [
            self::ISVERIFY_ENABLE => '通过',
            self::ISVERIFY_DISABLE => '否决',
            //self::ISVERIFY_WAIT => '取消',
        ];
    }

    /**
     * 返回绑定列表 
     */
    public static function getIsusedList()
    {
        return [
            self::ISUSED_ENABLE => '解绑',
            self::ISUSED_DISABLE => '绑定',
        ];
    }

    /**
     * 插入更新前置操作
     */
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            //判断是否是插入操作
            if ($this->isNewRecord) {
                $this->user_id = Yii::$app->user->id;
                $this->ip = Yii::$app->getRequest()->getUserIP();
                $this->create_time = time();
            } elseif ($this->isverify == self::ISVERIFY_DISABLE) {
                $this->isverify = 0;

                //若操作为新增，则向审核人发送系统通知
                $url = '/reimbursement/application/detail';
                $title = $this->name.'-'.Yii::$app->user->identity->realname;
                $content = Yii::$app->user->identity->realname . '于' . date('Y-m-d H:m:s', time()) . '提交申请单“' . $this->name . '”';
                $content .= ' <a target="_blank" href="' . Url::to([$url, 'id' => $this->appli_id]) . '">点击查看</a>';
                Announcement::Send($title, $content, explode(',', $this->verify_ids), 3);

                //$verify = Verify::deleteVerify('appli', $this->appli_id);
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 插入更新后置操作
     */
    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        if ($insert) {
            //若操作为新增，则向审核人发送系统通知
            $url = '/reimbursement/application/detail';
            $title = $this->name.'-'.Yii::$app->user->identity->realname;
            $content = Yii::$app->user->identity->realname . '于' . date('Y-m-d H:m:s', time()) . '提交申请单“' . $this->name . '”';
            $content .= ' <a target="_blank" href="' . Url::to([$url, 'id' => $this->appli_id]) . '">点击查看</a>';
            Announcement::Send($title, $content, explode(',', $this->verify_ids), 3);
        }

        \qcbase\models\ActionLog::insertLog('home', '修改', json_encode($changedAttributes));
    }

    /**
     * 权限审核
     * @param  string  $url     操作URL
     * @param  integer $user_id 用户ID
     */
    public static function readAccess($url = null, $user_id = 0)
    {
        if (empty($url)) {
            return false;
        }
        empty($user_id) ? $user_id = \Yii::$app->user->id : $user_id;
        //非超级管理员，需要检测权限
        if (Yii::$app->session->get('isSuperAdmin')) {
            return true;
        }
        //检测是否具有查看所有计划权限
        if (Auth::checkAccess($url, $user_id)) {
            return true;
        }
        return false;
    }

    /**
     * 某项费用申请的某项操作对当前用户是否有操作权限
     * 
     * @param string $action 当前操作
     * @param integer $appli_id 需要验证的申请单id
     * @return boolean 有权限返回true，没有则返回false
     */
    public static function checkAccess($action = null, $appli_id = 0)
    {
        if (empty($action) || empty($appli_id)) {
            return false;
        }

        $data = self::findOne(['appli_id' => $appli_id]);

        switch ($action) {
            case 'detail':
                $detailUser = PermissionScope::getScopeUser('reimbursement/application/detail');
                if (!empty($detailUser) && !in_array($data->user_id, $detailUser)) {
                    return false;
                }
                break;

            case 'view':
                $viewUser = PermissionScope::getScopeUser('reimbursement/application/view');
                if ($data->isverify == Application::ISVERIFY_DISABLE && !(!empty($viewUser) && !in_array($data->user_id, $viewUser))) {
                    break;
                } elseif ($data->isverify == Application::ISVERIFY_WAIT && (in_array(Yii::$app->user->id, explode(',', $data->verify_ids)) || empty($viewUser))) {
                    break;
                }else {
                    return false;
                }

            case 'update':
                $viewUser = PermissionScope::getScopeUser('reimbursement/application/update');
                if ($data->isverify == Application::ISVERIFY_DISABLE && !(!empty($viewUser) && !in_array($data->user_id, $viewUser))) {
                    break;
                } elseif ($data->isverify == Application::ISVERIFY_WAIT && (in_array(Yii::$app->user->id, explode(',', $data->verify_ids)) || empty($viewUser))) {
                    break;
                }else {
                    return false;
                }
                
            case 'verify':
                if ($data->isverify == Application::ISVERIFY_WAIT && in_array(Yii::$app->user->id, explode(',', $data->verify_ids)) && Application::readAccess('reimbursement/application/verify')) {
                    break;
                } else {
                    return false;
                }

            case 'delete':
                $deleteUser = PermissionScope::getScopeUser('reimbursement/application/delete');
                if ((!empty($deleteUser) && !in_array($data->user_id, $deleteUser)) || $data->isverify == Application::ISVERIFY_ENABLE) {
                    return false;
                }
                break;

            case 'set-status':
                if ($data->isverify == Application::ISVERIFY_WAIT && in_array(Yii::$app->user->id, explode(',', $data->verify_ids)) && Application::readAccess('reimbursement/application/verify')) {
                    break;
                } else {
                    return false;
                }

            default:
                return false;
            }

        return true;
    }

    /**
     * 获取申请人直属上级领导
     * @return [type] [description]
     */
    public static function getDeptLeader()
    {
        $user_list = Yii::$app->cache->get('user_list');
        if (!isset($user_list)) {
            throw new ErrorException('请更新缓存');
        }
        $user_id = Yii::$app->user->id;
        /* if (Yii::$app->session->get('isSuperAdmin')) {
          $leader_id = 1;
          } else { */
        $pk = (Yii::$app->cache->get('application_config')['application_user_select'] == 'verify') ? 'verify_user_id' : 'lead_user_id';
        $leader_id = UserDepartment::getDeptLeaderByUser($user_id, 'reimbursement/application/verify', $pk);
        //}
        return [
            'leader_id' => $leader_id,
            'leader_name' => $user_list[$leader_id]['realname']
        ];
    }
}
