['label' => '报单预存', 'value' => 1], 2 => ['label' => '结算自动扣除', 'value' => 2], 3 => ['label' => '调整复销池余额', 'value' => 3], 4 => ['label' => '调整复销池月数', 'value' => 4], 5 => ['label' => '手工扣除月复销', 'value' => 5], //7 => ['label' => '补发区域津贴', 'value' => 7], ]; /** * 可用复销余额 * @param $userId * @return mixed */ public static function getBalance($userId) { $oneData = ReconsumePool::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $userId], 'UNUSED_PV'); return $oneData['UNUSED_PV']; } /** * 增加复销或扣除复销池的PV * @param $userId * @param $pv * @param array $params * @param bool $mustHasUser * 该参数主要用于批量报单,复销会员是新首购的新会员,数据库中不存在该会员,此时不能要求一定存在会员,然后先把复销池数据插进去 * @return int * @throws Exception * @throws \yii\db\Exception */ public static function changePoolPV($userId, $pv, $params = [], $mustHasUser = true) { if ($pv == 0) return 0; $period = Period::instance(); if (!isset($params['PERIOD_NUM'])) { $periodNum = $period->getNowPeriodNum(); } else { $periodNum = $params['PERIOD_NUM']; } $calcYearMonth = $period->getYearMonth($periodNum); // 查看是否有数据 if (!ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->exists()) { // 新建一条用户的复销池数据 ReconsumePool::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]); } // 如果扣除pv的话,检测是否够扣,不够扣,则返回0 if ($pv < 0) { $oneDataBefore = ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one(); if ($oneDataBefore['UNUSED_PV'] < abs($pv)) { throw new Exception('复销池余额不足'); } } $updateData = []; $updateData['UNUSED_PV'] = new Expression("UNUSED_PV + $pv"); // 变更复销池Pv ReconsumePool::updateAll($updateData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]); unset($updateData); // 获取变更完的数据 $oneDataAfter = ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one(); // 记录流水 if($mustHasUser){ $userInfo = Info::baseInfo($userId); } else { $userInfo =[ 'DEC_LV' => DeclarationLevel::getDefaultLevelId(), 'EMP_LV' => EmployLevel::getDefaultLevelId(), 'STATUS' => 1, ]; } $flowInsertData = [ 'RECONSUME_POOL_SN' => ReconsumePoolFlow::generateSN(), 'USER_ID' => $userId, 'LAST_DEC_LV' => $userInfo['DEC_LV'], 'LAST_EMP_LV' => $userInfo['EMP_LV'], 'LAST_STATUS' => $userInfo['STATUS'], 'DEAL_TYPE' => $params['DEAL_TYPE'], 'RECONSUME_POOL_TYPE' => ReconsumePoolFlow::POOL_TYPE_PV, 'DEDUCT_PV' => $pv, 'UNUSED_PV' => $oneDataAfter['UNUSED_PV'], 'UNUSED_MONTH' => $oneDataAfter['UNUSED_MONTH'], 'REMARK' => $params['REMARK'] ?? null, 'REMARK_IS_SHOW' => $params['REMARK_IS_SHOW'] ?? 1, 'PERIOD_NUM' => $periodNum, 'CALC_MONTH' => $calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), 'ADMIN_NAME' => $params['ADMIN_NAME'] ?? null, ]; ReconsumePoolFlow::insertOne($flowInsertData); unset($flowInsertData); return $pv; } /** * 扣除月复销 * @param $userId * @param $periodNum * @param array $params * @return bool * @throws \yii\db\Exception */ public static function deductFx($userId, $periodNum, array $params = []) { $period = Period::instance(); $calcYearMonth = $period->getYearMonth($periodNum); return self::deductFxByCalcMonth($userId, $calcYearMonth, $params); } /** * 通过结算月来扣复销 * @param $userId * @param $calcYearMonth * @param array $params * @return bool * @throws Exception * @throws \yii\db\Exception */ public static function deductFxByCalcMonth($userId, $calcYearMonth, array $params = []) { $sysConfig = Cache::getSystemConfig(); $pv = $sysConfig['reConsumePerf']['VALUE']; // 看是否本月注册,本月注册不扣除@190904 if(Status::isMonthJoin($userId,$calcYearMonth)) return true; // 查看是否有数据 if (!ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->exists()) { // 新建一条用户的复销池数据 ReconsumePool::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]); } // 查看这个月是否已经扣过了,如果扣过了就不在扣了!直接返回扣除过的业绩 $isDeducted = ReconsumePoolFlow::find()->yearMonth($calcYearMonth)->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH AND IS_FX_DEDUCT=1', [':USER_ID' => $userId, ':CALC_MONTH' => $calcYearMonth])->asArray()->one(); if ($isDeducted) { return true; } // 检测是否够扣,不够扣,则扣除月有效期 $deductPv = 0; $deductMonth = 0; $oneDataBefore = ReconsumePool::find()->select('UNUSED_PV,UNUSED_MONTH')->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one(); if ($oneDataBefore['UNUSED_PV'] < abs($pv)) { if ($oneDataBefore['UNUSED_MONTH'] < abs(1)) { return false; } else { $deductMonth = 1; } } else { $deductPv = $pv; } $updateData = []; $updateData['UNUSED_PV'] = new Expression("UNUSED_PV - $deductPv"); $updateData['UNUSED_MONTH'] = new Expression("UNUSED_MONTH - $deductMonth"); // 变更复销池Pv ReconsumePool::updateAll($updateData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]); // 获取变更完的数据 $oneDataAfter = ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one(); // 获取该结算月的最大期数,即为结算月的期节点 $periodNum = Period::getPeriodNumPointFromMonth(substr($calcYearMonth, 0, 4), intval(substr($calcYearMonth, 4, 2))); // 记录流水 $userInfo = Info::baseInfo($userId); $flowInsertData = [ 'RECONSUME_POOL_SN' => ReconsumePoolFlow::generateSN(), 'USER_ID' => $userId, 'LAST_DEC_LV' => $userInfo['DEC_LV'], 'LAST_EMP_LV' => $userInfo['EMP_LV'], 'LAST_STATUS' => $userInfo['STATUS'], 'DEAL_TYPE' => $params['DEAL_TYPE'], 'RECONSUME_POOL_TYPE' => $deductMonth != 0 ? ReconsumePoolFlow::POOL_TYPE_MONTH : ReconsumePoolFlow::POOL_TYPE_PV, 'DEDUCT_PV' => $deductPv == 0 ? 0 : -$deductPv, 'DEDUCT_MONTH' => $deductMonth == 0 ? 0 : -$deductMonth, 'UNUSED_PV' => $oneDataAfter['UNUSED_PV'], 'UNUSED_MONTH' => $oneDataAfter['UNUSED_MONTH'], 'IS_FX_DEDUCT' => 1, 'REMARK' => $params['REMARK'] ?? null, 'REMARK_IS_SHOW' => $params['REMARK_IS_SHOW'] ?? 1, 'PERIOD_NUM' => $periodNum, 'CALC_MONTH' => $calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), 'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system', ]; ReconsumePoolFlow::insertOne($flowInsertData); unset($oneDataBefore, $updateData, $oneDataAfter, $flowInsertData); return true; } /** * 查看该会员是否能扣除复销 * @param $userId * @param $calcYearMonth * @return bool * @throws \yii\db\Exception */ public static function isCanDeduct($userId, $calcYearMonth) { // 查看会员是否本月加入 if (Status::isMonthJoin($userId, $calcYearMonth)) return false; // 会员未加入的结算月不允许扣除 if (Status::afterMonthJoin($userId, $calcYearMonth)) return false; // 查看该结算月是否已经扣过 return !(ReconsumePoolFlow::find()->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH AND IS_FX_DEDUCT=1', [':USER_ID' => $userId, ':CALC_MONTH' => $calcYearMonth])->exists()); } /** * 是否有得奖资格 * @param $userId * @param $calcYearMonth * @return bool * @throws \yii\db\Exception */ public static function isCanGetBonus($userId, $calcYearMonth) { // 查看会员是否本月加入 if (Status::isMonthJoin($userId, $calcYearMonth)) return true; // 查看会员上月是否已经扣除过复销 $periodNum = Period::getPeriodNumPointFromMonth(substr($calcYearMonth, 0, 4), intval(substr($calcYearMonth, 4, 2))); $period = Period::instance(); $lastMonth = $period->getLastMonth($periodNum); // 查看业绩表中该结算月的上个月是否有复销资格 return PerfMonth::find()->yearMonth($lastMonth['yearMonth'])->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH AND FX_STATUS=1', [':USER_ID' => $userId, ':CALC_MONTH' => $lastMonth['yearMonth']])->exists(); // return ReconsumePoolFlow::find()->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH AND IS_FX_DEDUCT=1', [':USER_ID'=>$userId, ':CALC_MONTH'=>$lastMonth['yearMonth']])->exists(); } /** * 变化有效月数 * @param $userId * @param $monthNum * @param array $params * @return int * @throws Exception * @throws \yii\db\Exception */ public static function changePoolMonthNum($userId, $monthNum, array $params = []) { $periodNum = $params['periodNum'] ?? null; if ($monthNum == 0) return 0; $period = Period::instance(); if (!$periodNum) { $periodNum = $period->getNowPeriodNum(); } $calcYearMonth = $period->getYearMonth($periodNum); // 查看是否有数据 if (!ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->exists()) { // 新建一条用户的复销池数据 ReconsumePool::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]); } // 如果扣除pv的话,检测是否够扣,不够扣,则返回0 if ($monthNum < 0) { $oneDataBefore = ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one(); if ($oneDataBefore['UNUSED_MONTH'] < abs($monthNum)) { throw new Exception('复销池剩余月数不足'); } } // 增加月份数 $updateData = []; $updateData['UNUSED_MONTH'] = new Expression("UNUSED_MONTH + $monthNum"); // 变更复销池Pv ReconsumePool::updateAll($updateData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]); // 获取变更完的数据 $oneDataAfter = ReconsumePool::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one(); // 记录流水 $userInfo = Info::baseInfo($userId); $flowInsertData = [ 'RECONSUME_POOL_SN' => ReconsumePoolFlow::generateSN(), 'USER_ID' => $userId, 'LAST_DEC_LV' => $userInfo['DEC_LV'], 'LAST_EMP_LV' => $userInfo['EMP_LV'], 'LAST_STATUS' => $userInfo['STATUS'], 'DEAL_TYPE' => $params['DEAL_TYPE'], 'RECONSUME_POOL_TYPE' => ReconsumePoolFlow::POOL_TYPE_MONTH, 'DEDUCT_MONTH' => $monthNum, 'UNUSED_PV' => $oneDataAfter['UNUSED_PV'], 'UNUSED_MONTH' => $oneDataAfter['UNUSED_MONTH'], 'REMARK' => $params['REMARK'] ?? null, 'REMARK_IS_SHOW' => $params['REMARK_IS_SHOW'] ?? 1, 'PERIOD_NUM' => $periodNum, 'CALC_MONTH' => $calcYearMonth, 'P_CALC_MONTH' => Date::ociToDate($calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH), 'CREATED_AT' => Date::nowTime(), 'ADMIN_NAME' => $params['ADMIN_NAME'] ?? null, ]; ReconsumePoolFlow::insertOne($flowInsertData); unset($updateData, $oneDataAfter, $flowInsertData); return $monthNum; } /** * 获取复销剩余时间 * @param $userId * @return array * @throws \yii\db\Exception */ public static function getUserReconsumePool($userId) { $pool = ReconsumePool::findUseSlaves()->select('UNUSED_PV,UNUSED_MONTH')->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one(); if (!$pool) { $pool['UNUSED_PV'] = 0; $pool['UNUSED_MONTH'] = 0; /*return [ 'unusedPV' => 0, 'unusedMonth' => 0, 'reConsumeTimes' => 0, 'toTime' => 0, 'toDate' => 0, ];*/ } // 第一步 获取复销剩余总月数 $systemConfig = Cache::getSystemConfig(); $reConsumePerf = $systemConfig['reConsumePerf']['VALUE']; if ($reConsumePerf <= 0) { return ['unusedPV' => 0, 'unusedMonth' => 0, 'reConsumeTimes' => 0, 'toTime' => 0, 'toDate' => 0, 'isPass' => 0, ]; } $reConsumeTimes = intval($pool['UNUSED_PV'] / $reConsumePerf); $reConsumeTimes += $pool['UNUSED_MONTH']; // 第二步 获取最近一次未挂网的结算月 $period = Period::instance(); $sentMaxPeriodNum = Period::sentMaxPeriodNum() + 1; $sentYear = $period->getYear($sentMaxPeriodNum); $sentMonth = Tool::numFix($period->getMonth($sentMaxPeriodNum), 2); $sentYearMonth = $period->getYearMonth($sentMaxPeriodNum); //看会员这个月是否复销 if (ReconsumePoolFlow::find()->yearMonth($sentYearMonth)->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH AND IS_FX_DEDUCT=1', [':USER_ID' => $userId, ':CALC_MONTH' => $sentYearMonth])->asArray()->one()) { //已扣复销当前月15日为时间基点 $baseDate = $sentYear . '-' . $sentMonth . '-15'; $reConsumeTimes += 1; } else { //获取上一个结算月 $lastMonth = $period->getLastMonth($sentMaxPeriodNum); $baseDate = $lastMonth['year'] . '-' . $lastMonth['month'] . '-15'; //是否本月注册会员 if (Status::isMonthJoin($userId, $sentYearMonth)) { $reConsumeTimes += 2; } //是否上月注册会员 elseif (Status::isMonthJoin($userId, $lastMonth['yearMonth'])) { $reConsumeTimes += 1; } elseif (Status::afterMonthJoin($userId, $sentYearMonth)){ $reConsumeTimes +=Period::getMonthNum($sentMaxPeriodNum,Info::getPeriodNumByUserId($userId)); $reConsumeTimes +=1; } else { //是否扣复销 if (!ReconsumePoolFlow::find()->yearMonth($lastMonth['yearMonth'])->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH AND IS_FX_DEDUCT=1', [':USER_ID' => $userId, ':CALC_MONTH' => $lastMonth['yearMonth']])->asArray()->one()) { //会员过期 if ($reConsumeTimes <= 0) { //上一次扣复销的时间 if ($flow = ReconsumePoolFlow::find()->select('PERIOD_NUM')->where('USER_ID=:USER_ID AND IS_FX_DEDUCT=1', [':USER_ID' => $userId])->orderBy('PERIOD_NUM DESC')->asArray()->one()) { $nextMonth = $period->getNextMonth($flow['PERIOD_NUM']); $overPeriod = Period::getPeriodPointFromMonth($nextMonth['year'], $nextMonth['month']); $toTime = $overPeriod['END_TIME']; $toPeriod = Period::getPeriodPointFromMonth($sentYear, $sentMonth); $toRechargeTime = $toPeriod['END_TIME']; return [ 'unusedPV' => $pool['UNUSED_PV'], 'unusedMonth' => $pool['UNUSED_MONTH'], 'reConsumeTimes' => 0, 'toTime' => $toTime, 'toDate' => \date('Y-m-d', $toTime), 'toRechargeTime' => $toRechargeTime, 'toRechargeDate' => \date('Y-m-d', $toRechargeTime), 'isPass' => 0, ]; } else { $nextMonth = $period->getNextMonth(Info::getPeriodNumByUserId($userId)); $overPeriod = Period::getPeriodPointFromMonth($nextMonth['year'], $nextMonth['month']); $toTime = $overPeriod['END_TIME']; $toPeriod = Period::getPeriodPointFromMonth($sentYear, $sentMonth); $toRechargeTime = $toPeriod['END_TIME']; return [ 'unusedPV' => $pool['UNUSED_PV'], 'unusedMonth' => $pool['UNUSED_MONTH'], 'reConsumeTimes' => 0, 'toTime' => $toTime, 'toDate' => \date('Y-m-d', $toTime), 'toRechargeTime' => $toRechargeTime, 'toRechargeDate' => \date('Y-m-d', $toRechargeTime), 'isPass' => 0, ]; } } else { $baseDate = $lastMonth['year'] . '-' . $lastMonth['month'] . '-15'; } }else{ $reConsumeTimes += 1; } } } $calcTime = strtotime("+$reConsumeTimes month", strtotime($baseDate)); //获取toTime结算月最后一期封期时间 $toPeriod = Period::getPeriodFromTime($calcTime); $periodPoint = Period::getPeriodPointFromMonth($toPeriod['CALC_YEAR'], $toPeriod['CALC_MONTH']); $toTime = $periodPoint['END_TIME']; $toDate = $toTime?(\date('Y-m-d', $toTime)):'长期'; $toRechargeTime = $periodPoint['END_TIME']; $toRechargeDate = $toRechargeTime?(\date('Y-m-d', $toRechargeTime)):'长期'; unset($toPeriod, $toYear, $toMonth, $periodPoint); return [ 'unusedPV' => $pool['UNUSED_PV'], 'unusedMonth' => $pool['UNUSED_MONTH'], 'reConsumeTimes' => $reConsumeTimes, 'toTime' => $toTime, 'toDate' => $toDate, 'toRechargeTime' => $toRechargeTime, 'toRechargeDate' => $toRechargeDate, 'isPass' => 1, ]; } /** * 通过用户名获取会员复销池相关 * @param $userName * @return array */ public static function getUserReconsumePoolByUserName($userName) { return self::getUserReconsumePool(Info::getUserIdByUserName($userName)); } /** * 不能扣除月复销的月份 * @param $userId * @param int|null $year * @return array|\yii\db\ActiveRecord[] * @throws \yii\db\Exception */ public static function cantDeductMonth($userId, int $year = null) { $period = Period::instance(); $sentMaxPeriodNum = Period::sentMaxPeriodNum() + 1; if ($year === null) { $year = $period->getYear($sentMaxPeriodNum); } $allData = ReconsumePoolFlow::find()->select('CALC_MONTH')->where('USER_ID=:USER_ID AND CALC_MONTH>=:YEAR_START AND CALC_MONTH<=:YEAR_END AND IS_FX_DEDUCT=1', [':USER_ID' => $userId, ':YEAR_START' => intval($year . '01'), ':YEAR_END' => intval($year . '12')])->asArray()->all(); //@190904 会员注册当月及以前都不能扣除 $oneUser = User::find()->select('PERIOD_AT')->where('ID=:USER_ID', [':USER_ID'=>$userId])->asArray()->one(); $period = Period::instance(); $addYear = $period->getYear($oneUser['PERIOD_AT']); if($addYear==$year){ $addMonth = $period->getMonth($oneUser['PERIOD_AT']); for($i=1;$i<=$addMonth;$i++){ $allData[] = ['CALC_MONTH'=>$year.Tool::numFix($i, 2)]; } } if($year == $period->getYear($sentMaxPeriodNum)){ $sentMonth = $period->getMonth($sentMaxPeriodNum); for($i=$sentMonth;$i<=12;$i++){ $allData[] = ['CALC_MONTH'=>$year.Tool::numFix($i, 2)]; } } return $allData; } }