변경 파일 목록
총 8개
변경 파일 코드
추가삭제
변경 전CouponAdmin.php
| } | |
| $arrData = []; | |
| $arrData['couponNo'] = $getValue['couponNo']; | |
| $arrData['couponSaveAdminId'] = Session::get('manager.managerId'); | |
| $arrData['managerNo'] = Session::get('manager.sno'); | |
| $arrData['memberCouponStartDate'] = $this->getMemberCouponStartDate($getValue['couponNo']); | |
| $arrData['memberCouponEndDate'] = $this->getMemberCouponEndDate($getValue['couponNo']); | |
| // 저장 | |
| $arrBind = $this->db->get_binding(DBTableField::tableMemberCoupon(), $arrData, 'insert', gd_array_keys($arrData), ['memberCouponNo']); | |
| $this->db->set_insert_db(DB_MEMBER_COUPON, $arrBind['param'], $arrBind['bind'], 'y'); | |
| $this->setCouponMemberSaveCount($getValue['couponNo']); | |
| } | |
| return 'T'; | |
| exit; | |
| } | |
변경 후CouponAdmin.php
| } | |
| $arrData = []; | |
| $arrData['couponNo'] = $getValue['couponNo']; | |
| $arrData['couponSaveAdminId'] = gd_isset(Request::post()->get('couponSaveAdminId'), Session::get('manager.managerId')); | |
| $arrData['managerNo'] = Session::get('manager.sno'); | |
| $arrData['memberCouponStartDate'] = $this->getMemberCouponStartDate($getValue['couponNo']); | |
| $arrData['memberCouponEndDate'] = $this->getMemberCouponEndDate($getValue['couponNo']); | |
| // 저장 | |
| $arrBind = $this->db->get_binding(DBTableField::tableMemberCoupon(), $arrData, 'insert', gd_array_keys($arrData), ['memberCouponNo']); | |
| $this->db->set_insert_db(DB_MEMBER_COUPON, $arrBind['param'], $arrBind['bind'], 'y'); | |
| } | |
| // 발급 카운트 일괄 증가 (루프 내 N회 UPDATE → 1회 UPDATE) | |
| $this->setCouponMemberSaveCountAll($getValue['couponNo'], count($memNoArr)); | |
| return 'T'; | |
| exit; | |
| } | |
변경 전MemberTableField.php
| 'typ' => 's', | |
| 'def' => null, | |
| ]; // 평생회원 전환일 | |
| return $arrField; | |
| } | |
변경 후MemberTableField.php
| 'typ' => 's', | |
| 'def' => null, | |
| ]; // 평생회원 전환일 | |
| $arrField[] = [ | |
| 'val' => 'autoGroupAppraisalDt', | |
| 'typ' => 's', | |
| 'def' => null, | |
| ]; // 회원등급평가 실행일 | |
| return $arrField; | |
| } | |
변경 전AppraisalMailSender.php
| use Component\Mail\MailUtil; | |
| use Component\Validator\Validator; | |
| /** | |
| public function send() | |
| { | |
| foreach ($this->receiver as $index => $item) { | |
| $groupVo = new \Component\Member\Group\GroupDomain($item[1]); | |
| if (!($groupVo instanceof GroupDomain)) { | |
| \App::getInstance('logger')->error('그룹정보 객체 오류', $item); | |
| continue; | |
| } | |
| MailUtil::sendMemberGroupChangeMail($item[0], $groupVo); | |
| } | |
| } | |
변경 후AppraisalMailSender.php
| use Component\Mail\MailUtil; | |
| use Component\Member\Group\GroupDomain; | |
| use Component\Validator\Validator; | |
| /** | |
| public function send() | |
| { | |
| // 같은 등급 GroupDomain을 재사용해 setGroupDcData()의 회원 수만큼 반복 DB조회(N+1)를 제거한다. | |
| $groupVoCache = []; | |
| foreach ($this->receiver as $index => $item) { | |
| $groupSno = isset($item[1]['sno']) ? $item[1]['sno'] : null; | |
| if ($groupSno !== null && isset($groupVoCache[$groupSno])) { | |
| $groupVo = $groupVoCache[$groupSno]; | |
| } else { | |
| $groupVo = new GroupDomain($item[1]); | |
| if (!($groupVo instanceof GroupDomain)) { | |
| \App::getInstance('logger')->error('그룹정보 객체 오류', $item); | |
| continue; | |
| } | |
| if ($groupSno !== null) { | |
| $groupVoCache[$groupSno] = $groupVo; | |
| } | |
| } | |
| MailUtil::sendMemberGroupChangeMail($item[0], $groupVo); | |
| } | |
| } | |
변경 전Appraisal.php
| namespace Bundle\Component\Member\Group; | |
| use App; | |
| use Component\Database\DBTableField; | |
| use Component\Member\Member; | |
| use Component\Sms\Code; | |
| use Framework\Utility\ComponentUtils; | |
| use Framework\Utility\DateTimeUtils; | |
| use Framework\Utility\NumberUtils; | |
| use Session; | |
| /** | |
| protected $search; | |
| /** @var AppraisalMailSender 등급평가 메일발송 */ | |
| protected $mailSender; | |
| /** @var array 등급평가 완료된 회원번호 */ | |
| protected $completeMemNo = []; | |
| /** @var string 등급평가일시 */ | |
| protected $appraisalDateTime; | |
| /** @var bool 현재 평가 등급 기준치 만족 여부 */ | |
| /** @var array 현재 평가대상 회원 */ | |
| protected $currentMembers; | |
| /** @var array 등급평가 제외 설정된 등급 sno 배열 */ | |
| protected $apprExclusionOfRating; | |
| /** @var array 그룹 sno별 등급 */ | |
| protected $groupSort; | |
| /** @var array 그룹 관리 설정 */ | |
| public $policy; | |
| /** @var array 기본 설정 */ | |
| public $basicInfo; | |
| /** | |
| * Appraisal constructor. | |
| * | |
| public function __construct(AppraisalSearch $search = null) | |
| { | |
| parent::__construct(); | |
| $this->setSearch($search); | |
| $this->groupConfig(); | |
| $this->validateAppraisalGroupConfig(); | |
| $this->policy = ComponentUtils::getPolicy('member.group'); | |
| $this->basicInfo = gd_policy('basic.info'); | |
| ini_set('memory_limit', '-1'); | |
| } | |
| } | |
| if ($data['apprSystem'] == 'point' && $data['appraisalPointOrderPriceFl'] != 'y' && $data['appraisalPointOrderRepeatFl'] != 'y' && $data['appraisalPointReviewRepeatFl'] != 'y' && $data['appraisalPointLoginRepeatFl'] != 'y') { | |
| $logger = \App::getInstance('logger'); | |
| $logger->warning('Not set appraisal performance point'); | |
| throw new Exception(__('실적 점수제 평가 설정 값이 없습니다.')); | |
| } | |
| $this->appraisalGroupConfig = new SimpleStorage($data); | |
| $validation->validateOverlapStandard(); | |
| $this->groupSort[$group['sno']] = $group['groupSort']; // 그룹 key: sno, value: sort 배열 생성 | |
| } | |
| // 회원등급 평가시 제외인 등급 그룹 배열 생성 | |
| $exclusionGroups = $dao->selectGroupExclusion(); | |
| foreach ($exclusionGroups as $key){ | |
| $this->groupConfig = $groups; | |
| } | |
| /** | |
| * setGroupNames | |
| * @return void | |
| */ | |
| public function appraisalGroupBySearch() | |
| { | |
| $logger = \App::getInstance('logger'); | |
| $logger->notice('Start group appraisal.'); | |
| $total = $this->countTotalMember(); | |
| $limit = $this->search->getAppraisalLimit(); | |
| $this->countByTotalMember = $this->appraisalCountByTotalMember($total, $limit); | |
| $logger->notice('총 회원[' . $total . '], 1회 평가당 제한 인원수[' . $limit . '], 평가 실행 횟수[' . $this->countByTotalMember . ']'); | |
| $this->completeMemNo = []; | |
| $this->appraisalDateTime = DateTimeUtils::dateFormat('Y-m-d H:i:s', 'now'); | |
| for ($offset = 0; $offset < $this->countByTotalMember; $offset++) { | |
| $this->appraisalGroupByOffset($offset); | |
| // 평가 대상으로 검색된 회원 초기화 | |
| $this->currentMembers = null; | |
| } | |
| $logger->notice('End group appraisal.'); | |
| } | |
| /** | |
| */ | |
| public function appraisalGroupByOffset($offset) | |
| { | |
| $logger = \App::getInstance('logger'); | |
| $db = \App::getInstance('DB'); | |
| $this->search->setAppraisalOffset($offset); | |
| $logger->info(sprintf('Start appraisal group set offset %s', $offset)); | |
| foreach ($this->groupConfig as $index => $item) { | |
| $db->ping(); | |
| $logger->info(sprintf('Start group name is %s, group sno is %s, group sort is %s', $item['groupNm'], $item['sno'], $item['groupSort'])); | |
| $this->group = new SimpleStorage($item); | |
| if ($this->currentMembers === null) { | |
| $this->currentMembers = $this->search->search($this->group); | |
| } | |
| if ($this->search->hasAppraisalMember($this->currentMembers)) { | |
| $logger->info(sprintf('has appraisal member count is %d', gd_count($this->currentMembers))); | |
| $this->updateGroupWithAddMailReceiver($this->currentMembers); | |
| } | |
| $logger->info(sprintf('End group name is %s, group sno is %s, group sort is %s', $item['groupNm'], $item['sno'], $item['groupSort'])); | |
| } | |
| if ($this->policy['downwardAdjustment'] == 'y') { | |
| $this->isDefaultGroupMember = true; | |
| $logger->info(sprintf('Start group name is %s, group sno is %s, group sort is %s', $this->defaultGroupConfig['groupNm'], $this->defaultGroupConfig['sno'], $this->defaultGroupConfig['groupSort'])); | |
| $this->group = new SimpleStorage($this->defaultGroupConfig); | |
| $this->search->setAppraisalDateTime($this->appraisalDateTime); | |
| $this->currentMembers = $this->search->searchDefaultGroup($this->appraisalDateTime); | |
| if ($this->search->hasAppraisalMember($this->currentMembers)) { | |
| $db->ping(); | |
| $logger->info(sprintf('has appraisal member count is %d', gd_count($this->currentMembers))); | |
| $this->updateGroupWithAddMailReceiver($this->currentMembers); | |
| } else { | |
| $logger->info('Not found appraisal members by default group', $this->defaultGroupConfig); | |
| } | |
| } | |
| $logger->info(sprintf('End group name is %s, group sno is %s, group sort is %s', $this->defaultGroupConfig['groupNm'], $this->defaultGroupConfig['sno'], $this->defaultGroupConfig['groupSort'])); | |
| $this->isDefaultGroupMember = false; | |
| } | |
| /** | |
| * appraisalMailSend | |
| * @return void | |
| */ | |
| public function updateGroupWithAddMailReceiver(array $members) | |
| { | |
| $logger = \App::getInstance('logger'); | |
| $session = \App::getInstance('session'); | |
| $db = \App::getInstance('DB'); | |
| try { | |
| $groupSno = $this->group->get('sno'); | |
| $settleGb = $this->group->get('settleGb'); | |
| $smsSender = \App::load(\Component\Sms\SmsSender::class); | |
| $smsSender->validPassword(\Request::post()->get('password')); | |
| } | |
| $count = 500; | |
| foreach ($members as $index => $item) { | |
| $count--; | |
| if ($count == 0) { | |
| $db->ping(); | |
| $count = 500; | |
| } | |
| $session->set(Member::SESSION_MODIFY_MEMBER_INFO, $item); | |
| $storage = new SimpleStorage($item); | |
| $storage->set('settleGb', $settleGb); | |
| $memNo = $storage->get('memNo'); | |
| array_push($this->completeMemNo, $memNo); | |
| // 현재 등급이 '등급평가시 제외' 설정이 아닐 때 | |
| if(gd_array_key_exists($item['groupSno'], $this->apprExclusionOfRating) == false) { | |
| $this->checkGroupByAppraisalSystem($item); | |
| $beforeGroupSort = $this->groupSort[$item['groupSno']]; | |
| $afterGroupSort = $this->groupSort[$groupSno]; | |
| //하향펑가를 설정하지 않았거나, 하향평가를 사용하거나, 하향평가를 사용하지 않고 변경 등급이 기존 등급보다 높거나 같을 때 만 업데이트 | |
| if (empty($this->policy['downwardAdjustment']) || $this->policy['downwardAdjustment'] == 'y' || ($this->policy['downwardAdjustment'] == 'n' && $beforeGroupSort < $afterGroupSort)) { | |
| if ($this->isCurrentGroupMember || $this->isDefaultGroupMember) { | |
| $logger->info('Group change target. sno[' . $this->group->get('sno', 0) . '], name[' . $this->group->get('', '-') . ']', $item); | |
| $this->updateGroup($memNo); | |
| $this->writeHistory($memNo); | |
| $this->addMailReceiver($storage, $this->group); | |
| $this->addSmsReceiver($storage, $this->group); | |
| unset($members[$index]); | |
| } | |
| } | |
| } | |
| } | |
| if ($this->isTran) { | |
| $db->commit(); | |
| $this->currentMembers = $members; | |
| } | |
| } catch (Exception $e) { | |
| $logger->error(__METHOD__ . ', ' . $e->getFile() . '[' . $e->getLine() . '], ' . $e->getMessage(), $e->getTrace()); | |
| $db->rollback(); | |
| } | |
| } | |
| /** | |
| * checkGroupByAppraisalSystem | |
| * | |
| * @param array $item 등급평가 대상의 기준치 정보 | |
| * | |
| } | |
| } | |
| if ($point > 0) { | |
| $logger = \App::getInstance('logger'); | |
| $logger->info( | |
| __METHOD__, [ | |
| 'memNo:'.$memNo, | |
| $point, | |
| */ | |
| public function checkGroupByFigure($item) | |
| { | |
| $logger = \App::getInstance('logger'); | |
| $this->isCurrentGroupMember = true; | |
| $priceUnit = 10000; | |
| */ | |
| public function updateGroupWithInsertHistory(SimpleStorage $storage) | |
| { | |
| $memNo = $storage->get('memNo'); | |
| $this->updateGroup($memNo); | |
| $this->writeHistory($memNo); | |
| } | |
| /** | |
| } | |
| } | |
| $passwordCheckFl = gd_isset(\Request::post()->get('passwordCheckFl'), 'y'); | |
| if($passwordCheckFl != 'n') { | |
| $smsSender = \App::load(\Component\Sms\SmsSender::class); | |
| $smsSender->validPassword(\Request::post()->get('password')); | |
| } | |
| $passwordCheckFl = $passwordCheckFl == 'n' ? false : true; | |
| //쿠폰 지급 하는 코드 | |
| if($applyCoupon === true){ | |
| $applyCouponList = explode(INT_DIVISION, $this->group->get('groupCoupon')); | |
| foreach($applyCouponList as $value){ | |
| $coupon = new \Component\Coupon\CouponAdmin; | |
| \Request::post()->set('couponNo', $value); | |
| \Request::post()->set('couponSaveAdminId', '회원등급 쿠폰 혜택'); | |
| \Request::post()->set('managerNo', Session::get('manager.sno')); | |
| \Request::post()->set('memberCouponStartDate', $coupon->getMemberCouponStartDate($value)); | |
| \Request::post()->set('memberCouponEndDate', $coupon->getMemberCouponEndDate($value)); | |
| \Request::post()->set('memberCouponState', 'y'); | |
| $memberArr[] = $memNo; | |
| $coupon->saveMemberCouponSms($memberArr, null, $passwordCheckFl); | |
| unset($memberArr); | |
| } | |
| } | |
| $db = \App::getInstance('DB'); | |
| $fields = DBTableField::getFieldTypes('tableMember'); | |
| $arrUpdate[] = 'groupSno=?'; | |
| $arrBind = []; | |
| $db->bind_param_push($arrBind, $fields['groupSno'], $this->group->get('sno')); | |
| $arrUpdate[] = 'groupModDt=?'; | |
| $db->bind_param_push($arrBind, $fields['groupModDt'], $this->appraisalDateTime); | |
| $db->bind_param_push($arrBind, $fields['memNo'], $memNo); | |
| $db->bind_param_push($arrBind, $fields['appFl'], 'y'); | |
| $db->bind_param_push($arrBind, $fields['sleepFl'], 'n'); | |
| $db->set_update_db(DB_MEMBER, $arrUpdate, 'memNo = ? AND appFl = ? AND sleepFl = ?', $arrBind); | |
| } | |
| $limit = $this->search->getAppraisalLimit(); | |
| // 처리 반복 횟수 계산 | |
| $countByTotalMember = $this->appraisalCountByTotalMember($total, $limit); | |
| $logger = \App::getInstance('logger'); | |
| $logger->notice('Start apply coupon to all members.'); | |
| $logger->notice('총 회원[' . $total . '], 1회 처리당 제한 인원수[' . $limit . '], 처리 실행 횟수[' . $countByTotalMember . ']'); | |
| //그룹 설정 가져오기 | |
| $group = \App::load('Component\Member\Group\GroupDAO'); | |
| $passwordCheckFl = gd_isset(\Request::post()->get('passwordCheckFl'), 'y'); | |
| if($passwordCheckFl != 'n') { | |
| // 쿠폰 관리 객체 미리 생성 | |
| $coupon = new \Component\Coupon\CouponAdmin; | |
| // 그룹별 쿠폰 정보 캐시 | |
| $groupList = []; | |
| // 페이징 처리를 위한 반복문 | |
| for ($offset = 0; $offset < $countByTotalMember; $offset++) { | |
| $start = $offset * $limit; | |
| $logger->info(sprintf('Start apply coupon with offset %s, limit %s', $start, $limit)); | |
| // 페이지별 회원 목록 조회 | |
| $memberPageList = $member->getMemberList($arrWhere, null, null, $start, $limit, $field); | |
| if (!empty($memberPageList) && gd_count($memberPageList) > 0) { | |
| foreach ($memberPageList as $key => $value) { | |
| //그룹 정보 가져오기 (캐시 활용) | |
| if (empty($groupList[$value['groupSno']])) { | |
| $groupList[$value['groupSno']] = $group->selectGroup($value['groupSno'])['groupCoupon']; | |
| } | |
| //하나씩 쿠폰 발급 하기 | |
| if (!empty($groupList[$value['groupSno']]) && gd_count($groupList[$value['groupSno']]) > 0) { | |
| $applyCouponList = explode(INT_DIVISION, $groupList[$value['groupSno']]); | |
| } | |
| if (!empty($applyCouponList) && gd_count($applyCouponList) > 0) { | |
| \Request::post()->set('couponSaveAdminId', '회원등급 쿠폰 혜택'); | |
| \Request::post()->set('memberCouponState', 'y'); | |
| \Request::post()->set('managerNo', Session::get('manager.sno')); | |
| $memberArr[] = $value['memNo']; | |
| foreach ($applyCouponList as $applyCoupon) { | |
| if (is_numeric($applyCoupon) && $applyCoupon > 0) { | |
| \Request::post()->set('couponNo', $applyCoupon); | |
| \Request::post()->set('memberCouponStartDate', $coupon->getMemberCouponStartDate($applyCoupon)); | |
| \Request::post()->set('memberCouponEndDate', $coupon->getMemberCouponEndDate($applyCoupon)); | |
| $coupon->saveMemberCouponSms($memberArr, null, $passwordCheckFl); | |
| } | |
| } | |
| unset($memberArr, $applyCouponList); | |
| } | |
| } | |
| } | |
| // 메모리 정리 | |
| unset($memberPageList); | |
| } | |
| $logger->notice('End apply coupon to all members.'); | |
| } | |
| /** | |
| */ | |
| public function addSmsReceiver(SimpleStorage $storage, SimpleStorage $group) | |
| { | |
| $logger = \App::getInstance('logger'); | |
| if ($storage->get('cellPhone') != null && $storage->get('memNm') != null) { | |
| if ($storage->get('beforeGroupSno') != $group->get('sno')) { | |
| $smsAuto = \App::load(\Component\Sms\SmsAuto::class); | |
| $observer = new SmsAutoObserver(); | |
| $observer->setSmsType(SmsAutoCode::MEMBER); | |
| $observer->setSmsAutoCodeType(Code::GROUP_CHANGE); | |
| $observer->setReceiver($storage->get('cellPhone')); | |
| $observer->setReplaceArguments( | |
| [ | |
| 'rc_groupNm' => $group->get('groupNm'), | |
| 'name' => $storage->get('memNm'), | |
| 'memNm' => $storage->get('memNm'), | |
| 'groupNm' => $group->get('groupNm'), | |
| 'rc_mallNm' => \Globals::get('gMall.mallNm'), | |
| 'shopUrl' => $this->basicInfo['mallDomain'], | |
| ); | |
| $smsAuto->attach($observer); | |
| } else { | |
| $logger->info(sprintf('The membership level is the same. before[%d], now[%d]', $storage->get('beforeGroupSno'), $group->get('sno'))); | |
| } | |
| } else { | |
| $logger->info(sprintf('Not have a cell phone number or member name. memNo[%d]', $storage->get('memNo', 0))); | |
| } | |
| } | |
| { | |
| return $this->appraisalGroupConfig->get('apprSystem') == 'point'; | |
| } | |
| } | |
변경 후Appraisal.php
| namespace Bundle\Component\Member\Group; | |
| use App; | |
| use Component\Coupon\CouponAdmin; | |
| use Component\Database\DBTableField; | |
| use Component\Member\Member; | |
| use Component\Sms\Code; | |
| use Framework\Utility\ComponentUtils; | |
| use Framework\Utility\DateTimeUtils; | |
| use Framework\Utility\NumberUtils; | |
| use Origin\Service\Member\Group\MemberGroupCouponService; | |
| use Origin\Service\Member\Group\MemberGroupService; | |
| use Session; | |
| /** | |
| protected $search; | |
| /** @var AppraisalMailSender 등급평가 메일발송 */ | |
| protected $mailSender; | |
| /** @var string 등급평가일시 */ | |
| protected $appraisalDateTime; | |
| /** @var bool 현재 평가 등급 기준치 만족 여부 */ | |
| /** @var array 현재 평가대상 회원 */ | |
| protected $currentMembers; | |
| /** @var array 등급평가 제외 설정된 등급 sno 배열 */ | |
| protected $apprExclusionOfRating = []; | |
| /** @var array 평가 대상 그룹 sno별 등급 */ | |
| protected $groupSort; | |
| /** @var array 평가 대상 여부와 무관한 전체 그룹 sno별 등급 */ | |
| protected $allGroupSort = []; | |
| /** @var array 그룹 관리 설정 */ | |
| public $policy; | |
| /** @var array 기본 설정 */ | |
| public $basicInfo; | |
| /** @var string 수행일자 */ | |
| public $targetDateTime; | |
| /** @var array es_member 필드 타입 */ | |
| protected $memberFields; | |
| /** @var object 로거 */ | |
| protected $logger; | |
| /** @var CouponAdmin 쿠폰 어드민 (updateGroup 내 쿠폰 발급 재사용) */ | |
| protected $couponAdmin; | |
| /** @var array [couponNo => [memNo, ...]] — updateGroup에서 누적 후 flush 로 쿠폰별 일괄 발급 */ | |
| protected $couponSmsBuffer = []; | |
| /** @var array rollback 된 배치의 memNo — 유지회원 stamp 제외 대상 */ | |
| protected $rolledBackMemNos = []; | |
| /** | |
| * Appraisal constructor. | |
| * | |
| public function __construct(AppraisalSearch $search = null) | |
| { | |
| parent::__construct(); | |
| $this->memberFields = DBTableField::getFieldTypes('tableMember'); | |
| $this->logger = App::getInstance('logger'); | |
| $this->setSearch($search); | |
| $this->groupConfig(); | |
| $this->validateAppraisalGroupConfig(); | |
| $this->policy = ComponentUtils::getPolicy('member.group'); | |
| $this->basicInfo = gd_policy('basic.info'); | |
| $this->couponAdmin = new CouponAdmin(); | |
| ini_set('memory_limit', '-1'); | |
| } | |
| } | |
| if ($data['apprSystem'] == 'point' && $data['appraisalPointOrderPriceFl'] != 'y' && $data['appraisalPointOrderRepeatFl'] != 'y' && $data['appraisalPointReviewRepeatFl'] != 'y' && $data['appraisalPointLoginRepeatFl'] != 'y') { | |
| $this->logger->warning('Not set appraisal performance point'); | |
| throw new Exception(__('실적 점수제 평가 설정 값이 없습니다.')); | |
| } | |
| $this->appraisalGroupConfig = new SimpleStorage($data); | |
| $validation->validateOverlapStandard(); | |
| $this->groupSort[$group['sno']] = $group['groupSort']; // 그룹 key: sno, value: sort 배열 생성 | |
| } | |
| $this->allGroupSort = (array)$this->groupSort; | |
| if ($isAppraisalFigure) { | |
| foreach ($dao->selectAppraisalGroups() as $group) { | |
| $this->allGroupSort[$group['sno']] = $group['groupSort']; | |
| } | |
| } | |
| // 회원등급 평가시 제외인 등급 그룹 배열 생성 | |
| $exclusionGroups = $dao->selectGroupExclusion(); | |
| foreach ($exclusionGroups as $key){ | |
| $this->groupConfig = $groups; | |
| } | |
| /** | |
| * 직전 평가일(autoAppraisalDateTime)은 배치 완료 후에 갱신되므로, 평가주기만큼 전진시켜 이번 회차를 찾는다. | |
| * | |
| * @param string $targetDate Y-m-d | |
| * | |
| * @return string Y-m-d | |
| */ | |
| protected function resolveAppraisalCycleStartDate($targetDate) | |
| { | |
| $calcCycleDay = (int)$this->getPolicyValue('calcCycleDay'); | |
| $base = date_create((string)$targetDate); | |
| if ($calcCycleDay < 1 || $base === false) { | |
| return $targetDate; | |
| } | |
| $base = date_create($base->format('Y-m-d')); | |
| $cycleStart = $this->resolveCycleStartByPreviousAppraisal($base, $calcCycleDay); | |
| if ($cycleStart === null) { | |
| $cycleStart = $this->cycleDateInMonth($base, $calcCycleDay); | |
| if ($cycleStart > $base) { | |
| $cycleStart = $this->cycleDateInMonth($this->shiftMonth($base, -1), $calcCycleDay); | |
| } | |
| } | |
| return $cycleStart->format('Y-m-d'); | |
| } | |
| /** | |
| * @param \DateTime $base | |
| * @param int $calcCycleDay | |
| * | |
| * @return \DateTime|null | |
| */ | |
| protected function resolveCycleStartByPreviousAppraisal(\DateTime $base, $calcCycleDay) | |
| { | |
| $calcCycleMonth = (int)$this->getPolicyValue('calcCycleMonth'); | |
| $previous = (string)$this->getPolicyValue('autoAppraisalDateTime'); | |
| if ($calcCycleMonth < 1 || $previous === '') { | |
| return null; | |
| } | |
| $cycleStart = date_create($previous); | |
| if ($cycleStart === false) { | |
| return null; | |
| } | |
| $cycleStart = date_create($cycleStart->format('Y-m-d')); | |
| if ($cycleStart > $base) { | |
| return null; | |
| } | |
| while (true) { | |
| $next = $this->cycleDateInMonth($this->shiftMonth($cycleStart, $calcCycleMonth), $calcCycleDay); | |
| if ($next > $base) { | |
| return $cycleStart; | |
| } | |
| $cycleStart = $next; | |
| } | |
| } | |
| /** | |
| * @param \DateTime $base | |
| * @param int $months | |
| * | |
| * @return \DateTime | |
| */ | |
| protected function shiftMonth(\DateTime $base, $months) | |
| { | |
| return date_create($base->format('Y-m-01'))->modify(sprintf('%+d month', $months)); | |
| } | |
| /** | |
| * @param \DateTime $base | |
| * @param int $calcCycleDay | |
| * | |
| * @return \DateTime | |
| */ | |
| protected function cycleDateInMonth(\DateTime $base, $calcCycleDay) | |
| { | |
| $day = min($calcCycleDay, (int)$base->format('t')); | |
| return date_create($base->format('Y-m-') . sprintf('%02d', $day)); | |
| } | |
| /** | |
| * @param string $key | |
| * | |
| * @return mixed | |
| */ | |
| protected function getPolicyValue($key) | |
| { | |
| return isset($this->policy[$key]) ? $this->policy[$key] : ''; | |
| } | |
| /** | |
| * @param int $groupSno | |
| * | |
| * @return int | |
| */ | |
| protected function resolveGroupSort($groupSno) | |
| { | |
| if (array_key_exists($groupSno, $this->allGroupSort)) { | |
| return (int)$this->allGroupSort[$groupSno]; | |
| } | |
| if (array_key_exists($groupSno, (array)$this->groupSort)) { | |
| return (int)$this->groupSort[$groupSno]; | |
| } | |
| $this->logger->warning('Not found groupSort. groupSno[' . $groupSno . ']'); | |
| return 0; | |
| } | |
| /** | |
| * setGroupNames | |
| * @return void | |
| */ | |
| public function appraisalGroupBySearch() | |
| { | |
| $this->logger->notice('Start group appraisal.'); | |
| $total = $this->countTotalMember(); | |
| $limit = $this->search->getAppraisalLimit(); | |
| $this->countByTotalMember = $this->appraisalCountByTotalMember($total, $limit); | |
| $this->logger->notice('총 회원[' . $total . '], 1회 평가당 제한 인원수[' . $limit . '], 평가 실행 횟수[' . $this->countByTotalMember . ']'); | |
| $this->appraisalDateTime = DateTimeUtils::dateFormat('Y-m-d H:i:s', 'now'); | |
| if (method_exists($this->search, 'setRequiredData')) { | |
| $this->search->setRequiredData($this->resolveRequiredData()); | |
| } | |
| for ($offset = 0; $offset < $this->countByTotalMember; $offset++) { | |
| $this->appraisalGroupByOffset($offset); | |
| // 평가 대상으로 검색된 회원 초기화 | |
| $this->currentMembers = null; | |
| } | |
| $this->logger->notice('End group appraisal.'); | |
| } | |
| /** | |
| */ | |
| public function appraisalGroupByOffset($offset) | |
| { | |
| $db = \App::getInstance('DB'); | |
| $this->search->setAppraisalOffset($offset); | |
| if (method_exists($this->search, 'setTargetDateTime')) { | |
| $this->search->setTargetDateTime($this->targetDateTime); | |
| } | |
| $this->logger->info(sprintf('Start appraisal group set offset %s', $offset)); | |
| foreach ($this->groupConfig as $index => $item) { | |
| $this->logger->info(sprintf('Start group name is %s, group sno is %s, group sort is %s', $item['groupNm'], $item['sno'], $item['groupSort'])); | |
| $this->group = new SimpleStorage($item); | |
| if ($this->currentMembers === null) { | |
| $this->currentMembers = $this->search->search($this->group); | |
| } | |
| if ($this->search->hasAppraisalMember($this->currentMembers)) { | |
| $this->logger->info(sprintf('has appraisal member count is %d', count($this->currentMembers))); | |
| $this->updateGroupWithAddMailReceiver($this->currentMembers); | |
| } | |
| $this->logger->info(sprintf('End group name is %s, group sno is %s, group sort is %s', $item['groupNm'], $item['sno'], $item['groupSort'])); | |
| } | |
| if ($this->policy['downwardAdjustment'] == 'y') { | |
| $this->isDefaultGroupMember = true; | |
| $this->logger->info(sprintf('Start group name is %s, group sno is %s, group sort is %s', $this->defaultGroupConfig['groupNm'], $this->defaultGroupConfig['sno'], $this->defaultGroupConfig['groupSort'])); | |
| $this->group = new SimpleStorage($this->defaultGroupConfig); | |
| $this->search->setAppraisalDateTime($this->appraisalDateTime); | |
| $this->currentMembers = $this->search->searchDefaultGroup($this->appraisalDateTime); | |
| if ($this->search->hasAppraisalMember($this->currentMembers)) { | |
| $this->logger->info(sprintf('has appraisal member count is %d', count($this->currentMembers))); | |
| $this->updateGroupWithAddMailReceiver($this->currentMembers); | |
| } else { | |
| $this->logger->info('Not found appraisal members by default group', $this->defaultGroupConfig); | |
| } | |
| } | |
| $this->logger->info(sprintf('End group name is %s, group sno is %s, group sort is %s', $this->defaultGroupConfig['groupNm'], $this->defaultGroupConfig['sno'], $this->defaultGroupConfig['groupSort'])); | |
| $this->isDefaultGroupMember = false; | |
| } | |
| /** | |
| * 특정 회원에 대한 그룹평가 | |
| * | |
| * @param array $memNos 타겟 memNo 배열 | |
| * appraisalGroupBySearch() 와 appraisalGroupByOffset() deprecate 및 해당 메서드로 대체 필요 | |
| */ | |
| public function evaluateGroup(array $memNos) | |
| { | |
| if (empty($memNos)) { | |
| return; | |
| } | |
| if (!method_exists($this->search, 'setTargetMembers')) { | |
| throw new Exception('AppraisalSearch 구버전 : 자동 등급평가는 신규 setTargetMembers/setRequiredData/setTargetDateTime 메서드가 필요합니다. AppraisalSearch.php 를 코어와 동기화해주세요.'); | |
| } | |
| $this->logger->notice('Start group appraisal.'); | |
| $this->appraisalDateTime = DateTimeUtils::dateFormat('Y-m-d H:i:s', 'now'); | |
| $this->search->setTargetDateTime($this->targetDateTime); | |
| $this->search->setTargetMembers($memNos); | |
| $this->search->setRequiredData($this->resolveRequiredData()); | |
| foreach ($this->groupConfig as $index => $item) { | |
| $this->logger->info(sprintf('Start group name is %s, group sno is %s, group sort is %s', $item['groupNm'], $item['sno'], $item['groupSort'])); | |
| $this->group = new SimpleStorage($item); | |
| if ($this->currentMembers === null) { | |
| $this->currentMembers = $this->search->search($this->group); | |
| } | |
| if ($this->search->hasAppraisalMember($this->currentMembers)) { | |
| $this->logger->info(sprintf('has appraisal member count is %d', count($this->currentMembers))); | |
| $this->updateGroupWithAddMailReceiver($this->currentMembers); | |
| } | |
| $this->logger->info(sprintf('End group name is %s, group sno is %s, group sort is %s', $item['groupNm'], $item['sno'], $item['groupSort'])); | |
| } | |
| if ($this->policy['downwardAdjustment'] == 'y') { | |
| $this->isDefaultGroupMember = true; | |
| $this->logger->info(sprintf('Start group name is %s, group sno is %s, group sort is %s', $this->defaultGroupConfig['groupNm'], $this->defaultGroupConfig['sno'], $this->defaultGroupConfig['groupSort'])); | |
| $this->group = new SimpleStorage($this->defaultGroupConfig); | |
| $this->search->setAppraisalDateTime($this->appraisalDateTime); | |
| $this->currentMembers = $this->search->searchDefaultGroup($this->appraisalDateTime); | |
| if ($this->search->hasAppraisalMember($this->currentMembers)) { | |
| $this->logger->info(sprintf('has appraisal member count is %d', count($this->currentMembers))); | |
| $this->updateGroupWithAddMailReceiver($this->currentMembers); | |
| } else { | |
| $this->logger->info('Not found appraisal members by default group', $this->defaultGroupConfig); | |
| } | |
| $this->logger->info(sprintf('End group name is %s, group sno is %s, group sort is %s', $this->defaultGroupConfig['groupNm'], $this->defaultGroupConfig['sno'], $this->defaultGroupConfig['groupSort'])); | |
| } | |
| $this->isDefaultGroupMember = false; | |
| $this->logger->notice('End group appraisal.'); | |
| } | |
| /** | |
| * appraisalMailSend | |
| * @return void | |
| */ | |
| public function updateGroupWithAddMailReceiver(array $members) | |
| { | |
| $session = \App::getInstance('session'); | |
| $db = \App::getInstance('DB'); | |
| $updateTargetMemNos = []; | |
| $pendingReceivers = []; | |
| try { | |
| $groupSno = $this->group->get('sno'); | |
| $settleGb = $this->group->get('settleGb'); | |
| $smsSender = \App::load(\Component\Sms\SmsSender::class); | |
| $smsSender->validPassword(\Request::post()->get('password')); | |
| } | |
| $checkGroupByPoint = $this->_isAppraisalSystemPoint(); | |
| foreach ($members as $index => $item) { | |
| $session->set(Member::SESSION_MODIFY_MEMBER_INFO, $item); | |
| $storage = new SimpleStorage($item); | |
| $storage->set('settleGb', $settleGb); | |
| $memNo = $storage->get('memNo'); | |
| // 현재 등급이 '등급평가시 제외' 설정이 아닐 때 | |
| if(array_key_exists($item['groupSno'], $this->apprExclusionOfRating) == false) { | |
| if ($checkGroupByPoint) { | |
| $this->checkGroupByPoint($item); | |
| } else { | |
| $this->checkGroupByFigure($item); | |
| } | |
| $beforeGroupSort = $this->resolveGroupSort($item['groupSno']); | |
| $afterGroupSort = $this->resolveGroupSort($groupSno); | |
| //하향펑가를 설정하지 않았거나, 하향평가를 사용하거나, 하향평가를 사용하지 않고 변경 등급이 기존 등급보다 높거나 같을 때 만 업데이트 | |
| if (empty($this->policy['downwardAdjustment']) || $this->policy['downwardAdjustment'] == 'y' || ($this->policy['downwardAdjustment'] == 'n' && $beforeGroupSort < $afterGroupSort)) { | |
| if ($this->isCurrentGroupMember || $this->isDefaultGroupMember) { | |
| $this->logger->info('Group change target. sno[' . $this->group->get('sno', 0) . '], name[' . $this->group->get('', '-') . ']', $item); | |
| $updateTargetMemNos[] = $memNo; | |
| $this->updateGroup($memNo); | |
| $this->writeHistory($memNo); | |
| $pendingReceivers[] = $storage; | |
| unset($members[$index]); | |
| } | |
| } | |
| } | |
| } | |
| // 쿠폰 발급은 회원 1명씩 호출하는 대신 쿠폰 번호별로 memNos 를 묶어 일괄 호출 | |
| if (!method_exists($this, 'flushCouponSmsBuffer')) { | |
| throw new Exception('Appraisal 구버전 감지: flushCouponSmsBuffer 메서드 누락. 등급평가 쿠폰 버퍼 일괄발급 로직 미적용 시 쿠폰 미발급이 발생할 수 있어 사전 차단합니다.'); | |
| } | |
| $this->flushCouponSmsBuffer(); | |
| if ($this->isTran) { | |
| $db->commit(); | |
| $this->currentMembers = $members; | |
| } | |
| foreach ($pendingReceivers as $receiver) { | |
| $this->addMailReceiver($receiver, $this->group); | |
| $this->addSmsReceiver($receiver, $this->group); | |
| } | |
| } catch (Exception $e) { | |
| $this->logger->error(__METHOD__ . ', ' . $e->getMessage(), ['exception' => $e]); | |
| $db->rollback(); | |
| $this->couponSmsBuffer = []; | |
| $this->rolledBackMemNos = array_merge($this->rolledBackMemNos, $updateTargetMemNos); | |
| if (method_exists($this->search, 'removeEvaluatedMemberSnapshots')) { | |
| $this->search->removeEvaluatedMemberSnapshots($updateTargetMemNos); | |
| } | |
| } | |
| } | |
| /** | |
| * @deprecated 반복문 내 다중 호출 시 성능 저하가 발생하므로 | |
| * 반복문 밖에서 한 번만 호출하여 결과를 캐싱해 사용하세요. | |
| * 향후 내부 로직에서 캐싱되거나 제거될 예정입니다. | |
| * | |
| * @param array $item 등급평가 대상의 기준치 정보 | |
| * | |
| } | |
| } | |
| if ($point > 0) { | |
| $this->logger->info( | |
| __METHOD__, [ | |
| 'memNo:'.$memNo, | |
| $point, | |
| */ | |
| public function checkGroupByFigure($item) | |
| { | |
| $this->isCurrentGroupMember = true; | |
| $priceUnit = 10000; | |
| */ | |
| public function updateGroupWithInsertHistory(SimpleStorage $storage) | |
| { | |
| $passwordCheckFl = gd_isset(\Request::post()->get('passwordCheckFl'), 'y'); | |
| if ($passwordCheckFl != 'n') { | |
| $smsSender = \App::load(\Component\Sms\SmsSender::class); | |
| $smsSender->validPassword(\Request::post()->get('password')); | |
| } | |
| $memNo = $storage->get('memNo'); | |
| $this->updateGroup($memNo); | |
| $this->writeHistory($memNo); | |
| if (!method_exists($this, 'flushCouponSmsBuffer')) { | |
| throw new Exception('Appraisal 구버전 감지: flushCouponSmsBuffer 메서드 누락. 등급평가 쿠폰 버퍼 일괄발급 로직 미적용 시 쿠폰 미발급이 발생할 수 있어 사전 차단합니다.'); | |
| } | |
| $this->flushCouponSmsBuffer(); | |
| } | |
| /** | |
| * updateGroup 루프에서 쌓인 쿠폰 발급 대상을 쿠폰 번호별로 묶어 일괄 발급. | |
| * 호출당 saveMemberCouponSms 내부 셋업 쿼리 (checkCouponType, getCouponInfo, | |
| * getMemberCouponStartDate/EndDate) 를 회원 수가 아닌 쿠폰 수 만큼만 수행. | |
| * | |
| * @return void | |
| */ | |
| public function flushCouponSmsBuffer() | |
| { | |
| if (empty($this->couponSmsBuffer)) { | |
| return; | |
| } | |
| $passwordCheckFlBool = \Request::post()->get('passwordCheckFl') == 'n' ? false : true; | |
| \Request::post()->set('couponSaveAdminId', '회원등급 쿠폰 혜택'); | |
| \Request::post()->set('managerNo', Session::get('manager.sno')); | |
| \Request::post()->set('memberCouponState', 'y'); | |
| foreach ($this->couponSmsBuffer as $couponNo => $memNos) { | |
| \Request::post()->set('couponNo', $couponNo); | |
| $result = $this->couponAdmin->saveMemberCouponSms($memNos, null, $passwordCheckFlBool); | |
| if ($result === false) { | |
| $this->logger->warning(sprintf('Coupon issue skipped (checkCouponType failed). couponNo[%d] memNo_cnt[%d]', $couponNo, count($memNos))); | |
| } | |
| } | |
| $this->couponSmsBuffer = []; | |
| } | |
| /** | |
| } | |
| } | |
| //쿠폰 지급 대상 버퍼에 적재 (실제 발급은 flushCouponSmsBuffer 에서 쿠폰별 일괄 호출) | |
| if($applyCoupon === true){ | |
| foreach(explode(INT_DIVISION, $this->group->get('groupCoupon')) as $value){ | |
| $couponNo = (int)$value; | |
| if ($couponNo > 0) { | |
| $this->couponSmsBuffer[$couponNo][] = $memNo; | |
| } | |
| } | |
| } | |
| $db = \App::getInstance('DB'); | |
| $arrUpdate[] = 'groupSno = ?'; | |
| $arrBind = []; | |
| $db->bind_param_push($arrBind, $this->memberFields['groupSno'], $this->group->get('sno')); | |
| $arrUpdate[] = 'groupModDt = ?'; | |
| $db->bind_param_push($arrBind, $this->memberFields['groupModDt'], $this->appraisalDateTime); | |
| $arrUpdate[] = 'autoGroupAppraisalDt = ?'; | |
| $db->bind_param_push($arrBind, $this->memberFields['autoGroupAppraisalDt'], $this->appraisalDateTime); | |
| $db->bind_param_push($arrBind, $this->memberFields['memNo'], $memNo); | |
| $db->bind_param_push($arrBind, $this->memberFields['appFl'], 'y'); | |
| $db->bind_param_push($arrBind, $this->memberFields['sleepFl'], 'n'); | |
| $db->set_update_db(DB_MEMBER, $arrUpdate, 'memNo = ? AND appFl = ? AND sleepFl = ?', $arrBind); | |
| } | |
| $limit = $this->search->getAppraisalLimit(); | |
| // 처리 반복 횟수 계산 | |
| $countByTotalMember = $this->appraisalCountByTotalMember($total, $limit); | |
| $this->logger->notice('Start apply coupon to all members.'); | |
| $this->logger->notice('총 회원[' . $total . '], 1회 처리당 제한 인원수[' . $limit . '], 처리 실행 횟수[' . $countByTotalMember . ']'); | |
| $passwordCheckFl = gd_isset(\Request::post()->get('passwordCheckFl'), 'y'); | |
| if($passwordCheckFl != 'n') { | |
| // 쿠폰 관리 객체 미리 생성 | |
| $coupon = new \Component\Coupon\CouponAdmin; | |
| // 쿠폰 정보 미리 생성 | |
| \Request::post()->set('couponSaveAdminId', '회원등급 쿠폰 혜택'); | |
| \Request::post()->set('memberCouponState', 'y'); | |
| \Request::post()->set('managerNo', Session::get('manager.sno')); | |
| // 그룹 쿠폰 정보 | |
| /** @var MemberGroupService $memberGroupService */ | |
| $memberGroupService = App::getInstance(MemberGroupService::class); | |
| $allGroupList = $memberGroupService->findAllGroupsKeyBySno(); | |
| // 페이징 처리를 위한 반복문 | |
| for ($offset = 0; $offset < $countByTotalMember; $offset++) { | |
| $start = $offset * $limit; | |
| $this->logger->info(sprintf('Start apply coupon with offset %s, limit %s', $start, $limit)); | |
| // 페이지별 회원 목록 조회 | |
| $memberPageList = $member->getMemberList($arrWhere, null, null, $start, $limit, $field); | |
| if (count($memberPageList) === 0) { | |
| continue; | |
| } | |
| foreach ($memberPageList as $memberInfo) { | |
| $groupCoupon = $allGroupList[$memberInfo['groupSno']]['groupCoupon'] ?? ''; | |
| if (empty($groupCoupon)) { | |
| continue; | |
| } | |
| $applyCouponList = explode(INT_DIVISION, $groupCoupon); | |
| // 하나씩 쿠폰 발급 하기 | |
| if (!empty($applyCouponList) && count($applyCouponList) > 0) { | |
| foreach ($applyCouponList as $applyCoupon) { | |
| if (is_numeric($applyCoupon) && $applyCoupon > 0) { | |
| \Request::post()->set('couponNo', $applyCoupon); | |
| \Request::post()->set('memberCouponStartDate', $coupon->getMemberCouponStartDate($applyCoupon)); | |
| \Request::post()->set('memberCouponEndDate', $coupon->getMemberCouponEndDate($applyCoupon)); | |
| $coupon->saveMemberCouponSms((array)$memberInfo['memNo'], null, $passwordCheckFl); | |
| } | |
| } | |
| unset($applyCouponList); | |
| } | |
| } | |
| // 메모리 정리 | |
| unset($memberPageList); | |
| } | |
| $this->logger->notice('End apply coupon to all members.'); | |
| } | |
| /** | |
| * 특정 회원에게 쿠폰 발급 | |
| * - 이미 등급평가를 통해 쿠폰이 발급된 회원 제외 | |
| * | |
| * applyCouponAllMember() 를 deprecate 및 해당 메서드로 대체 필요 | |
| * @param string $targetDate 대상일자 | |
| * @param array $memNos 대상 회원번호 배열 | |
| * | |
| * @return void | |
| */ | |
| public function applyCouponSpecificMember(string $targetDate, array $memNos) | |
| { | |
| if (empty($memNos)) { | |
| return; | |
| } | |
| $this->logger->notice('Start apply coupon to specific members.'); | |
| $passwordCheckFl = gd_isset(\Request::post()->get('passwordCheckFl'), 'y'); | |
| if($passwordCheckFl != 'n') { | |
| $smsSender = \App::load(\Component\Sms\SmsSender::class); | |
| $smsSender->validPassword(\Request::post()->get('password')); | |
| } | |
| $passwordCheckFl = $passwordCheckFl == 'n' ? false : true; | |
| // 쿠폰의 경우 재수행되었을 때 구분할 수 있는 값이 필요하여 대상일자를 추가함 | |
| $couponSaveAdminId = '회원등급 쿠폰 혜택(' . str_replace('-','', $targetDate) . ')'; | |
| \Request::post()->set('couponSaveAdminId', $couponSaveAdminId); | |
| \Request::post()->set('memberCouponState', 'y'); | |
| \Request::post()->set('managerNo', Session::get('manager.sno')); | |
| /** @var MemberGroupCouponService $memberGroupCouponService */ | |
| $memberGroupCouponService = App::getInstance(MemberGroupCouponService::class); | |
| $memberGroupCouponService->applyGroupCouponsToMembers( | |
| $memNos, | |
| $couponSaveAdminId, | |
| $passwordCheckFl, | |
| $targetDate, | |
| $this->resolveAppraisalCycleStartDate($targetDate) | |
| ); | |
| } | |
| /** | |
| * 변경자는 updateGroup 에서 이미 stamp 되므로, 유지자만 보완해 동일자 재평가 대상에서 제외되도록 한다. | |
| * | |
| * @param array $memNos | |
| * @param string $targetDate Y-m-d | |
| * | |
| * @return void | |
| */ | |
| public function updateAppraisalCompletedForDefaultGroupMembers(array $memNos, string $targetDate) | |
| { | |
| if (empty($memNos)) { | |
| return; | |
| } | |
| if (!method_exists($this->search, 'getEvaluatedMemberSnapshots')) { | |
| throw new Exception('AppraisalSearch 구버전 감지: getEvaluatedMemberSnapshots 누락. 평가 스냅샷 없이 유지회원 stamp 시 미평가 회원까지 평가완료 처리되어 다음 회차에서 누락될 수 있어 사전 차단합니다.'); | |
| } | |
| $db = \App::getInstance('DB'); | |
| $touchDateTime = $this->appraisalDateTime ?: ($targetDate . ' 00:00:00'); | |
| $from = $targetDate . ' 00:00:00'; | |
| $snapshots = $this->search->getEvaluatedMemberSnapshots(); | |
| $exclusion = $this->apprExclusionOfRating ?? []; | |
| $appraisalGroupSnos = $this->resolveAppraisalGroupSnos(); | |
| if (empty($appraisalGroupSnos)) { | |
| $this->logger->warning('Skip retained member stamp. Not found appraisal target group.', [ | |
| 'groupSort' => $this->groupSort, | |
| 'exclusion' => $exclusion, | |
| ]); | |
| return; | |
| } | |
| if (empty($snapshots)) { | |
| // 평가 검색이 실행되지 않은 실행(평가기준 그룹 없음 등) — 종전 라이브 조회 방식으로 stamp | |
| $memNos = array_values(array_diff($memNos, $this->rolledBackMemNos)); | |
| if (empty($memNos)) { | |
| return; | |
| } | |
| $arrBind = []; | |
| $db->bind_param_push($arrBind, 's', $touchDateTime); | |
| $placeholders = implode(',', array_fill(0, count($memNos), '?')); | |
| foreach ($memNos as $memNo) { | |
| $db->bind_param_push($arrBind, 'i', $memNo); | |
| } | |
| $db->bind_param_push($arrBind, 's', 'y'); | |
| $db->bind_param_push($arrBind, 's', 'n'); | |
| $groupPlaceholders = implode(',', array_fill(0, count($appraisalGroupSnos), '?')); | |
| foreach ($appraisalGroupSnos as $sno) { | |
| $db->bind_param_push($arrBind, 'i', $sno); | |
| } | |
| $db->bind_param_push($arrBind, 's', $from); | |
| $strWhere = 'memNo IN (' . $placeholders . ')' | |
| . ' AND appFl = ?' | |
| . ' AND sleepFl = ?' | |
| . ' AND groupSno IN (' . $groupPlaceholders . ')' | |
| . ' AND (autoGroupAppraisalDt IS NULL OR autoGroupAppraisalDt < ?)'; | |
| $db->set_update_db(DB_MEMBER, 'autoGroupAppraisalDt = ?', $strWhere, $arrBind); | |
| $this->logger->info('Update autoGroupAppraisalDt for retained members (no snapshot fallback)', [ | |
| 'table' => DB_MEMBER, | |
| 'memNoCount' => count($memNos), | |
| 'from' => $from, | |
| ]); | |
| return; | |
| } | |
| $retainedMemNos = $this->resolveRetainedStampTargets($snapshots, $exclusion, $appraisalGroupSnos); | |
| if (empty($retainedMemNos)) { | |
| return; | |
| } | |
| $arrBind = []; | |
| $db->bind_param_push($arrBind, 's', $touchDateTime); | |
| $placeholders = implode(',', array_fill(0, count($retainedMemNos), '?')); | |
| foreach ($retainedMemNos as $memNo) { | |
| $db->bind_param_push($arrBind, 'i', $memNo); | |
| } | |
| $db->bind_param_push($arrBind, 's', 'y'); | |
| $db->bind_param_push($arrBind, 's', 'n'); | |
| $db->bind_param_push($arrBind, 's', $from); | |
| $strWhere = 'memNo IN (' . $placeholders . ')' | |
| . ' AND appFl = ?' | |
| . ' AND sleepFl = ?' | |
| . ' AND (autoGroupAppraisalDt IS NULL OR autoGroupAppraisalDt < ?)'; | |
| $db->set_update_db(DB_MEMBER, 'autoGroupAppraisalDt = ?', $strWhere, $arrBind); | |
| $this->logger->info('Update autoGroupAppraisalDt for retained members', [ | |
| 'table' => DB_MEMBER, | |
| 'memNoCount' => count($retainedMemNos), | |
| 'from' => $from, | |
| ]); | |
| } | |
| /** | |
| * @param array $snapshots memNo => search 결과 row | |
| * @param array $exclusion 제외그룹 sno => sno | |
| * @param array $appraisalGroupSnos 평가 대상 등급 sno 배열 | |
| * | |
| * @return array | |
| */ | |
| public function resolveRetainedStampTargets(array $snapshots, array $exclusion, array $appraisalGroupSnos) | |
| { | |
| $retainedMemNos = []; | |
| $appraisalGroupSnos = array_map('intval', $appraisalGroupSnos); | |
| foreach ($snapshots as $memNo => $row) { | |
| $groupSno = is_array($row) ? ($row['groupSno'] ?? null) : null; | |
| if ($groupSno !== null && array_key_exists($groupSno, $exclusion)) { | |
| continue; | |
| } | |
| if ($groupSno !== null && in_array((int)$groupSno, $appraisalGroupSnos, true) === false) { | |
| continue; | |
| } | |
| $retainedMemNos[] = (int)$memNo; | |
| } | |
| return $retainedMemNos; | |
| } | |
| /** | |
| * @return array | |
| */ | |
| public function resolveAppraisalGroupSnos() | |
| { | |
| $groupSnos = array_keys((array)$this->groupSort); | |
| $exclusionSnos = array_values((array)$this->apprExclusionOfRating); | |
| return array_values(array_diff($groupSnos, $exclusionSnos)); | |
| } | |
| /** | |
| */ | |
| public function addSmsReceiver(SimpleStorage $storage, SimpleStorage $group) | |
| { | |
| if ($storage->get('cellPhone') != null && $storage->get('memNm') != null) { | |
| if ($storage->get('beforeGroupSno') != $group->get('sno')) { | |
| $smsAuto = \App::load(\Component\Sms\SmsAuto::class); | |
| $observer = new SmsAutoObserver(); | |
| $observer->setSmsType(SmsAutoCode::MEMBER); | |
| $observer->setSmsAutoCodeType(Code::GROUP_CHANGE); | |
| $observer->setReceiver([ | |
| 'memNo' => $storage->get('memNo'), | |
| 'memNm' => $storage->get('memNm'), | |
| 'smsFl' => $storage->get('smsFl', 'y'), | |
| 'cellPhone' => $storage->get('cellPhone'), | |
| ]); | |
| $observer->setReplaceArguments( | |
| [ | |
| 'rc_groupNm' => $group->get('groupNm'), | |
| 'name' => $storage->get('memNm'), | |
| 'memNm' => $storage->get('memNm'), | |
| 'memNo' => $storage->get('memNo'), | |
| 'groupNm' => $group->get('groupNm'), | |
| 'rc_mallNm' => \Globals::get('gMall.mallNm'), | |
| 'shopUrl' => $this->basicInfo['mallDomain'], | |
| ); | |
| $smsAuto->attach($observer); | |
| } else { | |
| $this->logger->info(sprintf('The membership level is the same. before[%d], now[%d]', $storage->get('beforeGroupSno'), $group->get('sno'))); | |
| } | |
| } else { | |
| $this->logger->info(sprintf('Not have a cell phone number or member name. memNo[%d]', $storage->get('memNo', 0))); | |
| } | |
| } | |
| { | |
| return $this->appraisalGroupConfig->get('apprSystem') == 'point'; | |
| } | |
| /* | |
| * 회원등급평가 타겟일자 셋팅 | |
| * | |
| * @param $targetDateTime 수행일자 | |
| */ | |
| public function setTargetDateTime($targetDateTime = null) | |
| { | |
| $this->targetDateTime = empty($targetDateTime) ? date('Y-m-d') : $targetDateTime; | |
| } | |
| /** | |
| * 전체 등급 설정을 스캔하여 실제 필요한 데이터 유형을 결정 | |
| * @return array ['order' => bool, 'review' => bool, 'login' => bool] | |
| */ | |
| protected function resolveRequiredData(): array | |
| { | |
| $isPoint = $this->_isAppraisalSystemPoint(); | |
| if ($isPoint) { | |
| return [ | |
| 'order' => $this->appraisalGroupConfig->get('appraisalPointOrderPriceFl', 'n') == 'y' | |
| || $this->appraisalGroupConfig->get('appraisalPointOrderRepeatFl', 'n') == 'y', | |
| 'review' => $this->appraisalGroupConfig->get('appraisalPointReviewRepeatFl', 'n') == 'y', | |
| 'login' => $this->appraisalGroupConfig->get('appraisalPointLoginRepeatFl', 'n') == 'y', | |
| ]; | |
| } | |
| // 수치제: 등급별 설정이므로 전체 등급을 스캔 | |
| $allGroups = array_merge($this->groupConfig, [$this->defaultGroupConfig]); | |
| $needsOrder = false; | |
| $needsReview = false; | |
| foreach ($allGroups as $group) { | |
| if (!$needsOrder && (($group['apprFigureOrderPriceFl'] ?? 'n') == 'y' || ($group['apprFigureOrderRepeatFl'] ?? 'n') == 'y')) { | |
| $needsOrder = true; | |
| } | |
| if (!$needsReview && ($group['apprFigureReviewRepeatFl'] ?? 'n') == 'y') { | |
| $needsReview = true; | |
| } | |
| if ($needsOrder && $needsReview) { | |
| break; | |
| } | |
| } | |
| return [ | |
| 'order' => $needsOrder, | |
| 'review' => $needsReview, | |
| 'login' => false, // 수치제에서는 로그인 기준 없음 | |
| ]; | |
| } | |
| } | |
변경 전AppraisalSearch.php
| private $periodQuery; | |
| /** @var string $periodDateFormat 검색기간 포맷 */ | |
| private $periodDateFormat = 'Y-m-d'; | |
| /** | |
| * 조회 | |
| unset($this->query, $this->column, $this->where); | |
| $this->periodQuery(); | |
| $this->boardQuery(); | |
| $this->orderQuery(); | |
| $this->loginQuery(); | |
| $this->buildQuery(); | |
| $logger->info(sprintf('Build query complete. %s', $this->query)); | |
| $results = $this->db->query_fetch($this->query); | |
| $logger->debug('Appraisal search result keys', gd_array_keys($results[0])); | |
| $return = []; | |
| foreach ($results as $index => $result) { | |
| if (gd_array_key_exists($result['memNo'], $return)) { | |
| $return[$result['memNo']] = $result; | |
| } | |
| return $return; | |
| } | |
| $query[] = 'SELECT memNo, COUNT(sno) AS cnt'; | |
| $query[] = ', COUNT(IF(loginCntMobile > 0, 1, NULL)) AS mcnt'; | |
| $query[] = 'FROM ' . DB_MEMBER_LOGINLOG; | |
| if ($this->usePeriod()) { | |
| $query[] = 'WHERE regDt ' . $this->periodQuery; | |
| } | |
| $query[] = 'GROUP BY memNo'; | |
| $this->loginQuery = '(' . gd_implode(' ', $query) . ')'; | |
| $query[] = ', COUNT(IF(isMobile=\'y\', sno, NULL)) AS mcnt'; | |
| $query[] = 'FROM ' . DB_BD_ . Board::BASIC_GOODS_REIVEW_ID; | |
| $query[] = 'WHERE memNo > 0'; | |
| if ($this->usePeriod()) { | |
| $query[] = 'AND regDt ' . $this->periodQuery; | |
| } | |
| $subQuery[] = 'LEFT JOIN ' . DB_ORDER_GOODS . ' AS og ON o.orderNo = og.orderNo'; | |
| $subQuery[] = 'LEFT JOIN ' . DB_ORDER_ADD_GOODS . ' AS oag ON o.orderNo = oag.orderNo'; | |
| $subQuery[] = 'WHERE og.orderStatus=\'s1\' AND o.memNo > 0'; | |
| if ($this->usePeriod()) { | |
| $subQuery[] = 'AND og.finishDt ' . $this->periodQuery; | |
| } | |
| unset($this->query, $this->column, $this->where); | |
| $this->periodQuery(); | |
| $this->boardQuery(); | |
| $this->orderQuery(); | |
| $this->loginQuery(); | |
| $this->buildQuery('m.groupSno!=' . $groupSno); | |
| $logger = \App::getInstance('logger'); | |
| $logger->info(sprintf('Build query complete. %s', $this->query)); | |
| */ | |
| public function searchDefaultGroup($appraisalDateTime) | |
| { | |
| $this->db->strField = 'm.memNo, m.memNm, m.email, m.cellPhone, m.groupSno, m.adminMemo, m.groupModDt'; | |
| // 다른등급 대상 회원 조회(_pushWhere())와 조건 동일하게 설정 | |
| $this->db->strWhere = 'm.sleepFl=\'n\' AND m.appFl=\'y\''; | |
| $this->db->strLimit = ($this->appraisalOffset * $this->appraisalLimit) . ', ' . $this->appraisalLimit; | |
| $this->db->strGroup = 'm.memNo'; | |
| $query = $this->db->query_complete(); | |
| $return[$result['memNo']] = $result; | |
| } | |
| } | |
| return $return; | |
| } | |
| if (!empty($where)) { | |
| $this->where[] = $where; | |
| } | |
| $this->db->strField = gd_implode(',', $this->column); | |
| $this->db->strWhere = gd_implode(' AND ', $this->where); | |
| $this->db->strJoin = 'LEFT JOIN ' . $this->boardQuery . ' AS b ON m.memNo = b.memNo'; | |
| $this->db->strJoin .= ' LEFT JOIN ' . $this->orderQuery . ' AS o ON m.memNo = o.memNo'; | |
| $this->db->strJoin .= ' LEFT JOIN ' . $this->loginQuery . ' AS l ON m.memNo = l.memNo'; | |
| $this->db->strLimit = ($this->appraisalOffset * $this->appraisalLimit) . ', ' . $this->appraisalLimit; | |
| $this->db->strGroup = 'm.memNo'; | |
| $query = $this->db->query_complete(); | |
| */ | |
| private function _pushColumn() | |
| { | |
| $this->column[] = 'm.memNo, m.memNm, m.email, m.cellPhone, m.groupSno, m.adminMemo, m.groupModDt'; | |
| $this->column[] = 'IFNULL(l.cnt, 0) AS loginCount'; | |
| $this->column[] = 'IFNULL(b.cnt, 0) AS reviewCount'; | |
| $this->column[] = 'IFNULL(o.cnt, 0) AS orderCount'; | |
| $this->column[] = 'IFNULL(o.price, 0) AS orderPrice'; | |
| $this->column[] = 'IFNULL(l.mcnt, 0) AS loginCountMobile'; | |
| $this->column[] = 'IFNULL(b.mcnt, 0) AS reviewCountMobile'; | |
| $this->column[] = 'IFNULL(o.mcnt, 0) AS orderCountMobile'; | |
| $this->column[] = 'IFNULL(o.mprice, 0) AS orderPriceMobile'; | |
| } | |
| /** | |
| $column = 'IFNULL(' . $column . ', 0)'; | |
| } | |
| } | |
| } | |
변경 후AppraisalSearch.php
| private $periodQuery; | |
| /** @var string $periodDateFormat 검색기간 포맷 */ | |
| private $periodDateFormat = 'Y-m-d'; | |
| /** @var string 수행일자 */ | |
| protected $targetDateTime; | |
| /** @var array airflow 가 지정한 memNo 배열 */ | |
| protected $targetMembers = []; | |
| /** @var array 실제 평가된 회원 스냅샷 (memNo => search 결과 row). 유지회원 stamp 대상 판정 기준 */ | |
| protected $evaluatedMembers = []; | |
| /** @var array 필요한 서브쿼리 플래그 ['order' => bool, 'review' => bool, 'login' => bool] */ | |
| protected $requiredData = ['order' => true, 'review' => true, 'login' => true]; | |
| /** | |
| * 조회 | |
| unset($this->query, $this->column, $this->where); | |
| $this->periodQuery(); | |
| if ($this->requiredData['review']) { | |
| $this->boardQuery(); | |
| } | |
| if ($this->requiredData['order']) { | |
| $this->orderQuery(); | |
| } | |
| if ($this->requiredData['login']) { | |
| $this->loginQuery(); | |
| } | |
| // 수동평가(targetMembers 없음)는 동일자 재평가 허용을 위해 완료대상 제외 필터 미적용 | |
| $this->buildQuery(empty($this->targetMembers) ? '' : $this->whereExcludeCompleteMember()); | |
| $logger->info(sprintf('Build query complete. %s', $this->query)); | |
| $results = $this->db->query_fetch($this->query); | |
| $logger->debug('Appraisal search result keys', empty($results) ? [] : array_keys($results[0])); | |
| $return = []; | |
| foreach ($results as $index => $result) { | |
| if (gd_array_key_exists($result['memNo'], $return)) { | |
| $return[$result['memNo']] = $result; | |
| } | |
| $logger->info(sprintf('Appraisal search matched %d of %d requested members. groupSno[%s]', count($return), count($this->targetMembers), $group->get('sno', '-'))); | |
| if (!empty($this->targetMembers)) { | |
| foreach ($return as $memNo => $row) { | |
| $this->evaluatedMembers[$memNo] = $row; | |
| } | |
| } | |
| return $return; | |
| } | |
| $query[] = 'SELECT memNo, COUNT(sno) AS cnt'; | |
| $query[] = ', COUNT(IF(loginCntMobile > 0, 1, NULL)) AS mcnt'; | |
| $query[] = 'FROM ' . DB_MEMBER_LOGINLOG; | |
| $loginWhere = []; | |
| if ($this->usePeriod()) { | |
| $loginWhere[] = 'regDt ' . $this->periodQuery; | |
| } | |
| if (!empty($this->targetMembers)) { | |
| $loginWhere[] = 'memNo IN (' . implode(',', array_map('intval', $this->targetMembers)) . ')'; | |
| } | |
| if (!empty($loginWhere)) { | |
| $query[] = 'WHERE ' . implode(' AND ', $loginWhere); | |
| } | |
| $query[] = 'GROUP BY memNo'; | |
| $this->loginQuery = '(' . gd_implode(' ', $query) . ')'; | |
| $query[] = ', COUNT(IF(isMobile=\'y\', sno, NULL)) AS mcnt'; | |
| $query[] = 'FROM ' . DB_BD_ . Board::BASIC_GOODS_REIVEW_ID; | |
| $query[] = 'WHERE memNo > 0'; | |
| if (!empty($this->targetMembers)) { | |
| $query[] = 'AND memNo IN (' . implode(',', array_map('intval', $this->targetMembers)) . ')'; | |
| } | |
| if ($this->usePeriod()) { | |
| $query[] = 'AND regDt ' . $this->periodQuery; | |
| } | |
| $subQuery[] = 'LEFT JOIN ' . DB_ORDER_GOODS . ' AS og ON o.orderNo = og.orderNo'; | |
| $subQuery[] = 'LEFT JOIN ' . DB_ORDER_ADD_GOODS . ' AS oag ON o.orderNo = oag.orderNo'; | |
| $subQuery[] = 'WHERE og.orderStatus=\'s1\' AND o.memNo > 0'; | |
| if (!empty($this->targetMembers)) { | |
| $subQuery[] = 'AND o.memNo IN (' . implode(',', array_map('intval', $this->targetMembers)) . ')'; | |
| } | |
| if ($this->usePeriod()) { | |
| $subQuery[] = 'AND og.finishDt ' . $this->periodQuery; | |
| } | |
| unset($this->query, $this->column, $this->where); | |
| $this->periodQuery(); | |
| if ($this->requiredData['review']) { | |
| $this->boardQuery(); | |
| } | |
| if ($this->requiredData['order']) { | |
| $this->orderQuery(); | |
| } | |
| if ($this->requiredData['login']) { | |
| $this->loginQuery(); | |
| } | |
| $where = 'm.groupSno != ' . $groupSno; | |
| if (!empty($this->targetMembers)) { | |
| $where .= ' AND ' . $this->whereExcludeCompleteMember(); | |
| } | |
| $this->buildQuery($where); | |
| $logger = \App::getInstance('logger'); | |
| $logger->info(sprintf('Build query complete. %s', $this->query)); | |
| */ | |
| public function searchDefaultGroup($appraisalDateTime) | |
| { | |
| $this->db->strField = 'm.memNo, m.memNm, m.email, m.cellPhone, m.smsFl, m.maillingFl, m.groupSno, m.adminMemo, m.groupModDt'; | |
| // 다른등급 대상 회원 조회(_pushWhere())와 조건 동일하게 설정 | |
| $this->db->strWhere = 'm.sleepFl=\'n\' AND m.appFl=\'y\''; | |
| if (!empty($this->targetMembers)) { | |
| $this->db->strWhere .= ' AND ' . $this->whereExcludeCompleteMember(); | |
| } | |
| if (empty($this->targetMembers)) { | |
| $this->db->strLimit = ($this->appraisalOffset * $this->appraisalLimit) . ', ' . $this->appraisalLimit; | |
| } else { | |
| $this->db->strWhere .= ' AND m.memNo IN (' . implode(',', array_map('intval', $this->targetMembers)) . ')'; | |
| } | |
| $this->db->strGroup = 'm.memNo'; | |
| $query = $this->db->query_complete(); | |
| $return[$result['memNo']] = $result; | |
| } | |
| } | |
| return $return; | |
| } | |
| if (!empty($where)) { | |
| $this->where[] = $where; | |
| } | |
| $this->db->strField = implode(',', $this->column); | |
| $this->db->strWhere = implode(' AND ', $this->where); | |
| $joins = []; | |
| if ($this->requiredData['review']) { | |
| $joins[] = 'LEFT JOIN ' . $this->boardQuery . ' AS b ON m.memNo = b.memNo'; | |
| } | |
| if ($this->requiredData['order']) { | |
| $joins[] = 'LEFT JOIN ' . $this->orderQuery . ' AS o ON m.memNo = o.memNo'; | |
| } | |
| if ($this->requiredData['login']) { | |
| $joins[] = 'LEFT JOIN ' . $this->loginQuery . ' AS l ON m.memNo = l.memNo'; | |
| } | |
| $this->db->strJoin = implode(' ', $joins); | |
| if (empty($this->targetMembers)) { | |
| $this->db->strLimit = ($this->appraisalOffset * $this->appraisalLimit) . ', ' . $this->appraisalLimit; | |
| } else { | |
| $this->db->strWhere .= ' AND m.memNo IN (' . implode(',', array_map('intval', $this->targetMembers)) . ')'; | |
| } | |
| $this->db->strGroup = 'm.memNo'; | |
| $query = $this->db->query_complete(); | |
| */ | |
| private function _pushColumn() | |
| { | |
| $this->column[] = 'm.memNo, m.memNm, m.email, m.cellPhone, m.smsFl, m.maillingFl, m.groupSno, m.adminMemo, m.groupModDt'; | |
| if ($this->requiredData['login']) { | |
| $this->column[] = 'IFNULL(l.cnt, 0) AS loginCount'; | |
| $this->column[] = 'IFNULL(l.mcnt, 0) AS loginCountMobile'; | |
| } else { | |
| $this->column[] = '0 AS loginCount'; | |
| $this->column[] = '0 AS loginCountMobile'; | |
| } | |
| if ($this->requiredData['review']) { | |
| $this->column[] = 'IFNULL(b.cnt, 0) AS reviewCount'; | |
| $this->column[] = 'IFNULL(b.mcnt, 0) AS reviewCountMobile'; | |
| } else { | |
| $this->column[] = '0 AS reviewCount'; | |
| $this->column[] = '0 AS reviewCountMobile'; | |
| } | |
| if ($this->requiredData['order']) { | |
| $this->column[] = 'IFNULL(o.cnt, 0) AS orderCount'; | |
| $this->column[] = 'IFNULL(o.price, 0) AS orderPrice'; | |
| $this->column[] = 'IFNULL(o.mcnt, 0) AS orderCountMobile'; | |
| $this->column[] = 'IFNULL(o.mprice, 0) AS orderPriceMobile'; | |
| } else { | |
| $this->column[] = '0 AS orderCount'; | |
| $this->column[] = '0 AS orderPrice'; | |
| $this->column[] = '0 AS orderCountMobile'; | |
| $this->column[] = '0 AS orderPriceMobile'; | |
| } | |
| } | |
| /** | |
| $column = 'IFNULL(' . $column . ', 0)'; | |
| } | |
| } | |
| public function setRequiredData(array $requiredData) | |
| { | |
| $this->requiredData = array_merge($this->requiredData, $requiredData); | |
| } | |
| /* | |
| * 회원등급평가 타겟일자 셋팅 | |
| * | |
| * @param string $targetDateTime 수행일자 | |
| */ | |
| public function setTargetDateTime($targetDateTime = null) | |
| { | |
| $this->targetDateTime = $targetDateTime; | |
| } | |
| public function setTargetMembers(array $target = []) | |
| { | |
| $this->targetMembers = $target; | |
| } | |
| public function getEvaluatedMemberSnapshots() | |
| { | |
| return $this->evaluatedMembers; | |
| } | |
| public function removeEvaluatedMemberSnapshots(array $memNos) | |
| { | |
| foreach ($memNos as $memNo) { | |
| unset($this->evaluatedMembers[$memNo]); | |
| } | |
| } | |
| /* | |
| * 타겟일자기준 회원등급평가 완료대상 제외 where 조건 | |
| * | |
| * @return string | |
| */ | |
| public function whereExcludeCompleteMember() | |
| { | |
| $from = $this->db->escape("{$this->targetDateTime} 00:00:00"); | |
| return "(m.autoGroupAppraisalDt IS NULL OR m.autoGroupAppraisalDt < '{$from}')"; | |
| } | |
| } | |
변경 전GroupDomain.php
| private $managerNo; | |
| private $regDt; | |
| private $modDt; | |
| function __construct(array $arr = null) | |
| { | |
| /** | |
| * 객체에 설정된 추가할인적용제외/중복할인적용에 대한 화면에 보여질 정보를 데이터베이스 조회를 통해 설정하는 함수 | |
| */ | |
| public function setGroupDcData() | |
| { | |
| $this->toStrip('dcExOption')->toJsonDecode('dcExOption', true); | |
| $this->toStrip('dcExScm')->toJsonDecode('dcExScm', true); | |
| $this->toStrip('dcExCategory')->toJsonDecode('dcExCategory', true); | |
| public function toStrip($key = null) | |
| { | |
| $this->$key = StringUtils::htmlSpecialCharsStripSlashes($this->$key); | |
| return $this; | |
| } | |
변경 후GroupDomain.php
| private $managerNo; | |
| private $regDt; | |
| private $modDt; | |
| /** @var bool setGroupDcData() 중복 실행 방지 플래그 */ | |
| private $isGroupDcDataSet = false; | |
| function __construct(array $arr = null) | |
| { | |
| /** | |
| * 객체에 설정된 추가할인적용제외/중복할인적용에 대한 화면에 보여질 정보를 데이터베이스 조회를 통해 설정하는 함수 | |
| * | |
| * 조회 결과를 원본 필드에 덮어쓰므로 두 번 호출하면 값이 깨진다. 인스턴스 재사용 시 최초 1회만 수행한다. | |
| */ | |
| public function setGroupDcData() | |
| { | |
| if ($this->isGroupDcDataSet) { | |
| return; | |
| } | |
| $this->isGroupDcDataSet = true; | |
| $this->toStrip('dcExOption')->toJsonDecode('dcExOption', true); | |
| $this->toStrip('dcExScm')->toJsonDecode('dcExScm', true); | |
| $this->toStrip('dcExCategory')->toJsonDecode('dcExCategory', true); | |
| public function toStrip($key = null) | |
| { | |
| // 캐시된 인스턴스를 회원 수만큼 재사용해도 멱등하게 동작한다. | |
| if (is_string($this->$key)) { | |
| $this->$key = StringUtils::htmlSpecialCharsStripSlashes($this->$key); | |
| } | |
| return $this; | |
| } | |
변경 전History.php
| $before = $session->get(Member::SESSION_MODIFY_MEMBER_INFO, null); | |
| $after = $this->db->getData(DB_MEMBER, $this->memNo, 'memNo'); | |
| MemberUtil::combineMemberData($before); | |
| MemberUtil::combineMemberData($after); | |
변경 후History.php
| $before = $session->get(Member::SESSION_MODIFY_MEMBER_INFO, null); | |
| $after = $this->db->getData(DB_MEMBER, $this->memNo, 'memNo'); | |
| // 자동 등급평가 등 세션 미세팅 경로에서 null 이 들어올 수 있음. | |
| // combineMemberData → ArrayUtils::unsetDiff(array $keys) 가 strict 타입이라 TypeError 발생 → 빈 배열로 보정. | |
| if (!is_array($before)) { | |
| $before = []; | |
| } | |
| if (!is_array($after)) { | |
| $after = []; | |
| } | |
| MemberUtil::combineMemberData($before); | |
| MemberUtil::combineMemberData($after); | |
변경 전MemberGroupPsController.php
| $appraisal = \App::load('\\Component\\Member\\Group\\Appraisal'); | |
| $appraisal->setRemoteAddress(Request::getRemoteAddress()); | |
| ini_set('max_execution_time', 0); | |
| $appraisal->appraisalGroupBySearch(); | |
| $appraisal->appraisalMailSend(); | |
| if($appraisal->policy['couponConditionComplete'] == 'y' && $appraisal->policy['couponConditionCompleteChange'] != 'y') { | |
변경 후MemberGroupPsController.php
| $appraisal = \App::load('\\Component\\Member\\Group\\Appraisal'); | |
| $appraisal->setRemoteAddress(Request::getRemoteAddress()); | |
| ini_set('max_execution_time', 0); | |
| if (!method_exists($appraisal, 'setTargetDateTime')) { | |
| throw new \Exception('Appraisal 구버전 감지: setTargetDateTime 메서드 누락. Appraisal.php 를 코어와 동기화해주세요.'); | |
| } | |
| $appraisal->setTargetDateTime(); | |
| $appraisal->appraisalGroupBySearch(); | |
| $appraisal->appraisalMailSend(); | |
| if($appraisal->policy['couponConditionComplete'] == 'y' && $appraisal->policy['couponConditionCompleteChange'] != 'y') { | |