32], [['PERIOD_NUM'], 'unique'], [['ID'], 'unique'], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'ID' => 'ID', 'PERIOD_NUM' => '期数', 'CALC_MONTH' => '结算月', 'CALC_YEAR' => '结算年', 'IS_SENT' => '是否已发放', 'CALCULATED_AT' => '结算完成时间', 'SENT_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->nowPeriodArr = $this->getNowPeriod(); } $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; } } public function getTeamsPeriodNum(){ $this->nowPeriodArr = static::find()->where('IS_SENT=0')->orderBy('PERIOD_NUM ASC')->asArray()->one(); // $this->nowPeriodArr = $this->getNowPeriod(); if($this->nowPeriodArr){ $this->setPeriodNum($this->nowPeriodArr['PERIOD_NUM']); return $this->nowPeriodArr['PERIOD_NUM']; } else { return self::SYSTEM_START_PERIOD_NUM; } } public function getNowPeriod() { $nowYear = date('Y'); $nowMonth = date('m'); return static::find() ->where('CALC_MONTH=:CALC_MONTH AND CALC_YEAR=:CALC_YEAR', [':CALC_MONTH' => $nowMonth, ':CALC_YEAR' => $nowYear]) ->asArray() ->one(); } /** * 获取当前期的开始时间 * @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; } } public function getTeamsYearMonth($periodNum){ $this->setPeriodNum($periodNum); 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 $year * @param $month * @return array */ public function getYearMonthAllPeriod($year, $month){ return Period::find()->select('PERIOD_NUM')->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->column(); } /** * 是否是结算月节点 * @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); LoggerTool::notice([$period, $period['IS_SENT'], self::SEND_FINISH, ($period['IS_SENT'] == self::SEND_FINISH), $period['START_TIME'] > time()]); if ($period['IS_SENT'] == self::SEND_FINISH) { return false; } // 有其他期正在计算中,不可以结算 // if ($period['CALCULATED_AT'] > 0) { // return false; // } // 下一期的开始已经大于本期的结束时间,不可以结算 if ($period['START_TIME'] > time()) { return false; } return true; } /** * 是否可以挂网 * @param $periodNum * @return bool */ public function isCanSend($periodNum = null){ $period = $this->setPeriodNum($periodNum); if($period['IS_PREPARE'] != 4){ return false; } if($period['IS_SENT'] == self::SEND_FINISH){ return false; } //上1期奖金未发放,限制不能挂网 $periodLast = self::findOneAsArray(['PERIOD_NUM' => $this->periodNum - 1]); if ($periodLast['IS_SENT'] != self::SEND_FINISH){ 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']; $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; } public static function getCurrentQuarterPeriodByPeriodNum($periodNum){ $currentPeriod = self::getInfoByPeriodNum($periodNum); $currentYear = $currentPeriod['CALC_YEAR']; $currentMonth = $currentPeriod['CALC_MONTH']; $periodsArray = self::find()->select("*") ->where(['CALC_YEAR'=>$currentYear]) ->andWhere(['in', 'CALC_MONTH', [$currentMonth-2, $currentMonth-1, $currentMonth]]) ->asArray()->all(); $periods = []; foreach ($periodsArray as $p){ $periods[] = $p['PERIOD_NUM']; } return $periods; } public static function updatePeriodIsAutoExec($periodNum, $isAutoExec = 0): int { return Period::updateAll(['AUTO_EXEC' => $isAutoExec], ['PERIOD_NUM' => $periodNum]); } public static function updatePeriodIsProcessing($periodNum, $isProcessing = 1): int { return Period::updateAll(['IS_PROCESSING' => $isProcessing], ['PERIOD_NUM' => $periodNum]); } public static function updatePeriodIsPreparing($periodNum, $isPreparing = 1): int { return Period::updateAll(['IS_PREPARING' => $isPreparing], ['PERIOD_NUM' => $periodNum]); } /** * 是否计算操作中 * @param $periodNum * @return bool */ public static function isProcessing($periodNum = null): bool { $db = CalcConsole::CALC_DB_NAME; $allPeriod = \Yii::$app->$db->createCommand("SELECT * FROM AR_PERIOD order by PERIOD_NUM desc")->queryAll(); $calcPeriod = []; foreach ($allPeriod as $v) { if ($v['IS_PREPARE'] > 0) { $calcPeriod = $v; break; } } $period = static::findOneAsArray(['PERIOD_NUM' => $periodNum]); // 若计算服务中CALC_ID不为空,则不允许计算 if ($calcPeriod) { if ($calcPeriod['CALC_ID']) return true; } //挂网则拒绝操作,返回true则拒绝操作 if ($period['IS_SENT'] == self::SEND_FINISH) return true; if ($period['IS_PROCESSING'] == self::IS_PROCESSING) return true; return false; } /** * 是否预计算操作中 * @param $periodNum * @return bool */ public static function isPreparing($periodNum = null): bool { $period = static::findOneAsArray(['PERIOD_NUM' => $periodNum]); //挂网则拒绝操作,返回true则拒绝操作 if ($period['IS_SENT'] == self::SEND_FINISH) return true; if ($period['IS_PREPARING'] == self::IS_PREPARING) return true; $nowTs = time(); if ($nowTs-6 > $period['END_TIME']) return true; return false; } public static function checkPerf($periodNum){ $result = static::find() ->where( 'PERIOD_NUM=:PERIOD_NUM ', [':PERIOD_NUM' => $periodNum] ) ->asArray() ->one(); if (isset($result['IS_PERFED']) && $result['IS_PERFED'] == 1) { return true; } return false; } public static function checkClose($periodNum){ $period = static::findOneAsArray(['PERIOD_NUM' => $periodNum]); if ($period['IS_CLOSED'] == 1) { return true; } return false; } /** * 获取期数列表 * @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')->limit($limit)->asArray()->all(); } else { $periodList = static::find()->select('PERIOD_NUM,IS_SENT,IS_CLOSED')->limit($limit)->column(); } return $periodList; } }