<?php

namespace common\models;

use common\helpers\Date;
use common\helpers\Tool;
use Yii;
use yii\db\Exception;

/**
 * This is the model class for table "{{%PERIOD}}".
 *
 * @property string $ID
 * @property int $PERIOD_NUM 期数
 * @property int $CALC_MONTH 所在结算月
 * @property int $CALC_YEAR 所在结算年
 * @property int $START_TIME 期数开始时间戳
 * @property int $END_TIME 期数结束时间戳
 * @property int $IS_MONTH 是否结算月节点
 * @property int $IS_YEAR 是否结算年节点
 * @property int $IS_CLOSED 是否已封期
 * @property int $IS_PERFED 是否已生成业绩单
 * @property int $IS_CALCULATED 是否已结算
 * @property int $IS_SENT 是否已发放
 * @property int $IS_PERFING 是否正在生成业绩单
 * @property int $IS_CALCING 是否正在计算状态
 * @property int $IS_SENDING 是否正在挂网状态
 * @property int $CALC_PERCENT 结算进度
 * @property int $SENT_PERCENT 发放进度
 * @property string $PERF_ADMIN_ID 生成业绩单管理员
 * @property string $CLOSE_ADMIN_ID 手动封期管理员ID
 * @property string $CALC_ADMIN_ID 结算管理员ID
 * @property string $SENT_ADMIN_ID 发放管理员ID
 * @property int $CLOSED_AT 发放管理员ID
 * @property int $PERF_STARTED_AT 生成业绩单开始时间
 * @property int $PERFED_AT 生成业绩单结束时间
 * @property int $CALCULATE_STARTED_AT 结算开始时间
 * @property int $CALCULATED_AT 结算完成时间
 * @property int $SEND_STARTED_AT 发放开始时间
 * @property int $SENT_AT 发放完成时间
 * @property int $CREATED_AT 创建时间
 */
class Period extends \common\components\ActiveRecord
{
    const CALCULATE_NONE = 0;
    const CALCULATE_FINISH = 1;
    const CALCULATE_FAIL = 2;

    const SEND_NONE = 0;
    const SEND_FINISH = 1;
    const SEND_FAIL = 2;

    const PERF_NONE = 0;
    const PERF_FINISH = 1;
    const PERF_FAIL = 2;

    const SYSTEM_START_PERIOD_NUM = 100;

    public $nowPeriodArr = null;
    public $periodNum = null;
    public $periodArr = null;

    public function init()
    {
        parent::init();
    }

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

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['PERIOD_NUM', 'CALC_MONTH', 'CALC_YEAR', 'START_TIME', 'END_TIME', 'CREATED_AT'], 'required'],
            [['PERIOD_NUM', 'CALC_MONTH', 'CALC_YEAR', 'START_TIME', 'END_TIME', 'IS_MONTH', 'IS_YEAR', 'IS_CLOSED', 'IS_PERFED', 'IS_CALCULATED', 'IS_SENT', 'IS_PERFING', 'IS_CALCING', 'IS_SENDING', 'CALC_PERCENT', 'SENT_PERCENT', 'CLOSED_AT', 'PERF_STARTED_AT', 'PERFED_AT', 'CALCULATE_STARTED_AT', 'CALCULATED_AT', 'SEND_STARTED_AT', 'SENT_AT', 'CREATED_AT'], 'integer'],
            [['ID', 'PERF_ADMIN_ID', 'CLOSE_ADMIN_ID', 'CALC_ADMIN_ID', 'SENT_ADMIN_ID'], 'string', 'max' => 32],
            [['PERIOD_NUM'], 'unique'],
            [['ID'], 'unique'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'ID' => 'ID',
            'PERIOD_NUM' => '期数',
            'CALC_MONTH' => '所在结算月',
            'CALC_YEAR' => '所在结算年',
            'START_TIME' => '期数开始时间戳',
            'END_TIME' => '期数结束时间戳',
            'IS_MONTH' => '是否结算月节点',
            'IS_YEAR' => '是否结算年节点',
            'IS_CLOSED' => '是否已封期',
            'IS_PERFED' => '是否已生成业绩单',
            'IS_CALCULATED' => '是否已结算',
            'IS_SENT' => '是否已发放',
            'IS_PERFING' => '是否正在生成业绩单',
            'IS_CALCING' => '是否正在计算状态',
            'IS_SENDING' => '是否正在挂网状态',
            'CALC_PERCENT' => '结算进度',
            'SENT_PERCENT' => '发放进度',
            'PERF_ADMIN_ID' => '生成业绩单管理员',
            'CLOSE_ADMIN_ID' => '手动封期管理员ID',
            'CALC_ADMIN_ID' => '结算管理员ID',
            'SENT_ADMIN_ID' => '发放管理员ID',
            'CLOSED_AT' => '发放管理员ID',
            'PERF_STARTED_AT' => '生成业绩单开始时间',
            'PERFED_AT' => '生成业绩单结束时间',
            'CALCULATE_STARTED_AT' => '结算开始时间',
            'CALCULATED_AT' => '结算完成时间',
            'SEND_STARTED_AT' => '发放开始时间',
            'SENT_AT' => '发放完成时间',
            'CREATED_AT' => '创建时间',
        ];
    }

    /**
     * 期数赋值给属性
     * @param int $periodNum
     * @return array|null|\yii\db\ActiveRecord
     */
    public function setPeriodNum($periodNum = null){
        if($periodNum === 0 || $periodNum === null || $periodNum === ''){
            //if($this->nowPeriodArr === null){
                $this->nowPeriodArr = static::find()->where('IS_CLOSED=0')->orderBy('PERIOD_NUM ASC')->asArray()->one();
            //}
            $this->periodArr = $this->nowPeriodArr;
            $periodNum = $this->nowPeriodArr['PERIOD_NUM'];
        } else {
            if($periodNum !== $this->periodNum){
                $this->periodArr = static::findOneAsArray(['PERIOD_NUM'=>$periodNum]);
            }
        }
        $this->periodNum = $periodNum;
        return $this->periodArr;
    }

    // 通过期数,获取此期数据
    public static function getInfoByPeriodNum($periodNum) {
        
        return static::findOneAsArray(['PERIOD_NUM'=>$periodNum]);
    }

    /**
     * 是否存在所传期数
     * @param int $periodNum
     * @return bool
     */
    public static function isExistsPeriodNum(int $periodNum){
        return static::find()->where(['PERIOD_NUM'=>$periodNum])->exists();
    }

    /**
     * 获取当前未封期的最小期数
     * @return int
     */
    public function getNowPeriodNum(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['PERIOD_NUM'];
        } else {
            return self::SYSTEM_START_PERIOD_NUM;
        }
    }

    /**
     * 获取当前期的开始时间
     * @return int
     */
    public function getNowPeriodStart(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['START_TIME'];
        } else {
            return Date::nowTime();
        }
    }

    /**
     * 获取当前期的结束时间
     * @return int
     */
    public function getNowPeriodEnd(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['END_TIME'];
        } else {
            return Date::nowTime();
        }
    }

    /**
     * 获取当前所在的结算月
     * @return int
     */
    public function getNowMonth(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['CALC_MONTH'];
        } else {
            return 0;
        }
    }

    /**
     * 获取当前期数所在结算年
     * @return int
     */
    public function getNowYear(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['CALC_YEAR'];
        } else {
            return 0;
        }
    }

    /**
     * 当前期数所在年月
     * @return int|string
     */
    public function getNowYearMonth(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['CALC_YEAR'].Tool::numFix($this->nowPeriodArr['CALC_MONTH']);
        } else {
            return 0;
        }
    }

    /**
     * 获取期数所在的结算月
     * @param int $periodNum
     * @return mixed
     * @throws Exception
     */
    public function getMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['CALC_MONTH'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 获取期数所在的结算年
     * @param $periodNum
     * @return mixed
     * @throws Exception
     */
    public function getYear($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['CALC_YEAR'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 期数所在年月
     * @param $periodNum
     * @return string
     * @throws Exception
     */
    public function getYearMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['CALC_YEAR'].Tool::numFix($period['CALC_MONTH'], 2);
        } else {
            throw new Exception('期数不存在'.$periodNum);
        }
    }

    /**
     * 所传年、月所有期数的数量
     * @param $year
     * @param $month
     * @return int
     */
    public function getYearMonthAllPeriodNumCount($year, $month){
        return Period::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->count(1);
    }

    /**
     * 是否是结算月节点
     * @param $periodNum
     * @return mixed
     * @throws Exception
     */
    public function isCalcMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['IS_MONTH'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 是否是结算年节点
     * @param $periodNum
     * @return mixed
     * @throws Exception
     */
    public function isCalcYear($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['IS_YEAR'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 获取挂网的最大期数
     * @return int
     */
    public function getMaxIsSentPeriodNum() {
        $maxIsSentData = static::find()->where('IS_SENT=1')->orderBy('PERIOD_NUM DESC')->asArray()->one();
        $maxIsSentPeriodNum = self::SYSTEM_START_PERIOD_NUM;
        if( $maxIsSentData && $maxIsSentData["PERIOD_NUM"] ) {
            $maxIsSentPeriodNum = $maxIsSentData["PERIOD_NUM"];
        }

        return $maxIsSentPeriodNum;
    }

    /**
     * 返回所传结算月包含的所有期数
     * @param $year
     * @param $month
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getPeriodNumsFromMonth($year, $month){
        return static::find()->select('PERIOD_NUM')->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->orderBy('PERIOD_NUM ASC')->asArray()->all();
    }

    /**
     * 获取所传结算月的最小期数和最大期数
     * @param $year
     * @param $month
     * @return array
     */
    public static function getPeriodNumRangeFromMonth($year, $month){
        $allPeriod = self::getPeriodNumsFromMonth($year, $month);
        $tempPeriod = [];
        foreach($allPeriod as $period){
            $tempPeriod[] = $period['PERIOD_NUM'];
        }
        if(!$tempPeriod){
            return null;
        }
        $minPeriod = min($tempPeriod);
        $maxPeriod = max($tempPeriod);
        return ['min'=>$minPeriod, 'max'=>$maxPeriod];
    }

    /**
     * 返回结算月的节点期数
     * @param $year
     * @param $month
     * @return mixed|null
     */
    public static function getPeriodNumPointFromMonth($year, $month) {
        $data = static::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH AND IS_MONTH=1', [':CALC_YEAR'=>$year, ':CALC_MONTH' => $month])->asArray()->one();
        if($data) return $data['PERIOD_NUM'];
        else return null;
    }

    /**
     * 返回结算月的节点期
     * @param $year
     * @param $month
     * @return mixed|null
     */
    public static function getPeriodPointFromMonth($year, $month) {
        $data = static::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH AND IS_MONTH=1', [':CALC_YEAR'=>$year, ':CALC_MONTH' => $month])->asArray()->one();
        if($data) return $data;
        else return null;
    }

    /**
     * 是否已经封期
     * @param $periodNum
     * @return bool
     * @throws Exception
     */
    public function isClosed($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return boolval($period['IS_CLOSED']);
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 是否已经生成业绩单
     * @param $periodNum
     * @return bool
     * @throws Exception
     */
    public function isPerfed($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return boolval($period['IS_PERFED']);
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 是否已结算
     * @param null $periodNum
     * @return bool
     * @throws Exception
     */
    public function isCalculated($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return boolval($period['IS_CALCULATED'] == self::CALCULATE_FINISH);
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 是否可被封期
     * @param $periodNum
     * @return bool
     */
    public function isCanClose($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period['IS_CLOSED']){
            return false;
        }
        $previousPeriod = static::findOne(['PERIOD_NUM'=>$this->periodNum-1]);
        if($previousPeriod){
            if(!$previousPeriod['IS_CLOSED']){
                return false;
            }
            // 只要上期封期了，下期就可以封期
//            if(!$previousPeriod['IS_CALCULATED']){
//                return false;
//            }
//            if(!$previousPeriod['IS_SENT']){
//                return false;
//            }
        }
        return true;
    }

    /**
     * 是否可以生成业绩单
     * @param $periodNum
     * @return bool
     */
    public function isCanPerf($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        // 查看该期是否已经封期
        if(!$period['IS_CLOSED']){
            return false;
        }
        // 已经挂网，不能生成业绩单
        if($period['IS_SENT'] == self::SEND_FINISH){
            return false;
        }
        //上1期奖金未发放，限制不能生成业绩单
        if(!$this->isLastSent($this->periodNum)){
            return false;
        }
        return true;
    }

    /**
     * 是否可以结算
     * @param $periodNum
     * @return bool
     */
    public function isCanCalc($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        // 查看该期是否已经封期
        if(!$period['IS_CLOSED']){
            return false;
        }
        // 还没有生成业绩单，不能封期
        if(!$period['IS_PERFED'] || $period['IS_PERFED'] == self::PERF_FAIL){
            return false;
        }
        if($period['IS_SENT'] == self::SEND_FINISH){
            return false;
        }
//        $previousPeriod = static::findOneAsArray(['PERIOD_NUM'=>$this->periodNum-1]);
//        if($previousPeriod){
//            // 查看上一期是否已经挂网，上一期挂网了，本期才能结算
//            if(!$previousPeriod['IS_SENT']){
//                return false;
//            }
//        }
        //上1期奖金未发放，限制不能结算
        if(!$this->isLastSent($this->periodNum)){
            return false;
        }

        return true;
    }

    /**
     * 是否可以挂网
     * @param $periodNum
     * @return bool
     */
    public function isCanSend($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if(!$period['IS_CLOSED']){
            return false;
        }
        if(!$period['IS_CALCULATED'] || $period['IS_CALCULATED'] == self::CALCULATE_FAIL){
            return false;
        }
        if($period['IS_SENT'] == self::SEND_FINISH){
            return false;
        }
        //上1期奖金未发放，限制不能挂网
        if(!$this->isLastSent($this->periodNum)){
            return false;
        }
        return true;
    }

    /**
     * 是否已经挂网
     * @param $periodNum
     * @return bool
     */
    public function isSent($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period['IS_SENT'] == self::SEND_FINISH) return true;
        return false;
    }

    /**
     * 上期是否挂网
     * @param null $periodNum
     * @return bool
     */
    public function isLastSent($periodNum){
        $period = $this->setPeriodNum($periodNum-1);
        if ($period) {
            if($period['IS_SENT'] == self::SEND_FINISH) { 
                return true;
            } else {
                return false;
            }
        }
        
        return false;
    }

    /**
     * 获取上月的年月
     * @param $periodNum
     * @return array
     */
    public function getLastMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            $year = $period['CALC_YEAR'];
            $month = $period['CALC_MONTH'];
            if($month=='13'){
                $lastYear = $year;
                $lastMonth = '12';
            } else if($month=='1'){
                $lastYear = Date::lastMonth($year.'-'.$month,'Y');
                $lastMonth = '13';
            } else {
                $lastYear = Date::lastMonth($year.'-'.$month, 'Y');
                $lastMonth = Date::lastMonth($year.'-'.$month, 'm');
            }
            return [
                'year' => $lastYear,
                'month' => intval($lastMonth),
                'yearMonth' => $lastYear.Tool::numFix($lastMonth, 2),
            ];
        } else {
            return [
                'year' => 0,
                'month' => 0,
                'yearMonth' => 0,
            ];
        }
    }

    /**
     * 上几个月的年月
     * @param int $num
     * @param null $periodNum
     * @return array
     */
    public function getLastNumMonth($num=1,$periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            $year = $period['CALC_YEAR'];
            $month = $period['CALC_MONTH'];
            $lastYear = Date::lastNumMonth($num,$year.'-'.$month, 'Y');
            $lastMonth = Date::lastNumMonth($num,$year.'-'.$month, 'm');
            return [
                'year' => $lastYear,
                'month' => intval($lastMonth),
                'yearMonth' => $lastYear.Tool::numFix($lastMonth, 2),
            ];
        } else {
            return [
                'year' => 0,
                'month' => 0,
                'yearMonth' => 0,
            ];
        }
    }

    /**
     * 下月的年月
     * @param null $periodNum
     * @return array
     */
    public function getNextMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            $year = $period['CALC_YEAR'];
            $month = $period['CALC_MONTH'];
            $nextYear = Date::nextMonth($year.'-'.$month, 'Y');
            $nextMonth = Date::nextMonth($year.'-'.$month, 'm');
            return [
                'year' => $nextYear,
                'month' => intval($nextMonth),
                'yearMonth' => $nextYear.Tool::numFix($nextMonth, 2),
            ];
        } else {
            return [
                'year' => 0,
                'month' => 0,
                'yearMonth' => 0,
            ];
        }
    }

    /**
     * 通过时间戳获取期
     * @param $time
     * @return array|null|\yii\db\ActiveRecord
     */
    public static function getPeriodFromTime($time){
        return static::find()->where('START_TIME<=:TIME AND END_TIME>:TIME', [':TIME'=>$time])->asArray()->one();
    }

    /**
     * 通过时间戳范围获取期间内的期
     * @param $minTime
     * @param $maxTime
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getPeriodFromTimeRange($minTime, $maxTime){
        return static::find()->where('END_TIME>:MIN_TIME AND START_TIME<:MAX_TIME', [':MIN_TIME'=>$minTime, ':MAX_TIME'=>$maxTime])->orderBy('PERIOD_NUM ASC')->asArray()->all();
    }

    /**
     * 获取近几期的期数
     * @param $num
     * @return array
     */
    public static function getNearlyPeriodNum($num){
        // 获取当前期
        $period = self::instance();
        $periodNum = $period->getNowPeriodNum();
        // 获取前$num期的期数
        $periodNums = [
            $periodNum
        ];
        for($i=0;$i<$num;$i++){
            if($periodNum - $i > 0){
                // 查看该期是否存在
                if(self::isExistsPeriodNum($periodNum - $i)){
                    $periodNums[] = $periodNum - $i;
                }
            }
        }
        return array_reverse($periodNums);
    }

    /**
     * 获取近几期的挂网期数
     * @param $num
     * @return array
     */
    public static function getNearlySendPeriodNum($num){
        // 获取当前期
        $period = self::instance();
        $periodNum = $period->sentMaxPeriodNum();
        // 获取前$num期的期数
        $periodNums = [
            $periodNum
        ];
        for($i=0;$i<$num;$i++){
            if($periodNum - $i > 0){
                // 查看该期是否存在
                if(self::isExistsPeriodNum($periodNum - $i)){
                    $periodNums[] = $periodNum - $i;
                }
            }
        }
        return array_reverse($periodNums);
    }

    /**
     * 获取近几期的年月
     * @param $num
     * @return array
     * @throws Exception
     */
    public static function getNearlyPeriodYearMonth($num){
        // 获取当前期
        $period = self::instance();
        $periodNum = $period->getNowPeriodNum();
        $nowYearMonth = $period->getNowYearMonth();
        // 获取前$num期的期数
        $periodYearMonths = [];
        for($i=1;$i<=$num;$i++){
            if($periodNum - $i > 0){
                // 查看该期是否存在
                if(self::isExistsPeriodNum($periodNum - $i)){
                    $yearMonth = $period->getYearMonth($periodNum - $i);
                    $periodYearMonths[] = [
                        'yearMonth' => $yearMonth,
                        'periodNum' => $periodNum - $i,
                    ];
                }
            }
        }
        return array_reverse($periodYearMonths);
    }

    /**
     * 获取本月所有已经挂网的期数
     * @param $yearMonth
     * @return array
     */
    public static function monthSentAllPeriodNum($yearMonth){
        $year = intval(substr($yearMonth, 0, 4));
        $month = intval(substr($yearMonth, 4, 2));
        $allPeriod = Period::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH AND IS_SENT=1', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->select('PERIOD_NUM')->asArray()->all();
        $result = [];
        if($allPeriod){
            foreach($allPeriod as $period){
                $result[] = $period['PERIOD_NUM'];
            }
        }
        return $result;
    }

    /**
     * 所传月份所有已结算的期数
     * @param $yearMonth
     * @return array
     */
    public static function monthCalcAllPeriodNum($yearMonth){
        $year = intval(substr($yearMonth, 0, 4));
        $month = intval(substr($yearMonth, 4, 2));
        $allPeriod = Period::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH AND IS_CALCING=1', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->select('PERIOD_NUM')->asArray()->all();
        $result = [];
        if($allPeriod){
            foreach($allPeriod as $period){
                $result[] = $period['PERIOD_NUM'];
            }
        }
        return $result;
    }

    /**
     * 获取已结算的最大期数
     * @return mixed
     */
    public static function calculatedMaxPeriodNum(){
        return static::find()->where('IS_CALCULATED=1')->max('PERIOD_NUM');
    }

    /**
     * 已挂网的最大期数
     * @return mixed
     */
    public static function sentMaxPeriodNum(){
        return static::find()->where('IS_SENT=1')->max('PERIOD_NUM');
    }

    /**
     * 期数结束时间
     * @param $periodNum
     * @return int|mixed
     */
    public static function getEndTime($periodNum) {
        $endTime = static::find()->where('PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $periodNum])->select('END_TIME')->asArray()->one();
        return $endTime['END_TIME'] ?? 0;
    }

    /**
     * 到年底的剩余月份
     * @param null $periodNum
     * @return int
     * @throws Exception
     */
    public static function getMonthLeft($periodNum = null) {
        $period = self::instance();
        if ($periodNum) {
            $nowMonth = $period->getMonth($periodNum);
        } else {
            $nowMonth = $period->getNowMonth();
        }
        return 12 - (int)$nowMonth + 1;
    }

    /**
     * 起始期数和结束期数几个月
     * @param $startPeriodNum
     * @param $endPeriodNum
     * @return int|string
     */
    public static function getMonthNum($startPeriodNum,$endPeriodNum){
        return self::find()->select('CALC_MONTH')->groupBy('CALC_MONTH')->where('PERIOD_NUM>=:START_PERIOD AND PERIOD_NUM<=:END_PERIOD',[':START_PERIOD'=>$startPeriodNum,':END_PERIOD'=>$endPeriodNum])->count();
    }

    /**
     * 从期数获取当前月的所有期
     *
     */
    public static function getCurrentMonthPeriodByPeriodNum($periodNum){
        $currentPeriod = self::getInfoByPeriodNum($periodNum);
        $currentYear = $currentPeriod['CALC_YEAR'];
        $currentMonth = $currentPeriod['CALC_MONTH'];
        $periodsArray = self::findAllAsArray(['CALC_YEAR'=>$currentYear,'CALC_MONTH'=>$currentMonth]);
        $periods = [];
        foreach ($periodsArray as $p){
            $periods[] = $p['PERIOD_NUM'];
        }

        return $periods;
    }

    /**
     * 获取期数列表
     * @param null $periodNum
     * @param int $limit
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getPeriodList($periodNum = null, $limit = 10) {
        if ($periodNum) {
            $periodList = static::find()->where('PERIOD_NUM >= :PERIOD_NUM', [':PERIOD_NUM' => $periodNum])->select('PERIOD_NUM,IS_SENT,IS_CLOSED')->limit($limit)->asArray()->all();
        } else {
            $periodList = static::find()->select('PERIOD_NUM,IS_SENT,IS_CLOSED')->limit($limit)->column();
        }
        return $periodList;
    }
}
