addClassName('Service'); } public function getModelClass(): ServiceModel { return new ServiceModel(); } public function getEntityClass(): ServiceEntity { return new ServiceEntity(); } public function getFormFields(): array { return [ "clientinfo_uid", "ownerinfo_uid", "type", "location", "switchinfo_uid", "codeinfo_uid", "raid", "billing_at", "start_at", "status" ]; } public function getFilterFields(): array { return ["clientinfo_uid", 'ownerinfo_uid', 'user_uid', 'type', 'location', 'switchinfo_uid', 'codeinfo_uid', 'raid', 'status']; } public function getBatchJobFields(): array { return ['status']; } public function getIndexFields(): array { return ['clientinfo_uid', 'ownerinfo_uid', 'type', 'location', 'switchinfo_uid', 'codeinfo_uid', 'raid', 'billing_at', 'start_at', 'updated_at', 'status', 'user_uid']; } public function getUSerService(): UserService { if (!$this->_userService) { $this->_userService = new UserService(); } return $this->_userService; } public function getCodeService(): CodeService { if (!$this->_codeService) { $this->_codeService = new CodeService(); } return $this->_codeService; } public function getSwitchService(): SwitchService { if (!$this->_switchService) { $this->_switchService = new SwitchService(); } return $this->_switchService; } public function getServiceItemService(): ServiceItemService { if (!$this->_serviceItemService) { $this->_serviceItemService = new ServiceItemService(); } return $this->_serviceItemService; } public function getServicePaymentService(): ServicePaymentService { if (!$this->_servicePaymentService) { $this->_servicePaymentService = new ServicePaymentService(); } return $this->_servicePaymentService; } //Entity의 관련객체정의용 public function setSearchIp(string $ip): void { $this->_searchIP = $ip; } public function getSearchIp(): string|null { return $this->_searchIP; } protected function findAllDatas(array $columns = ['*']): mixed { $ip = $this->getSearchIp(); if ($ip) { $sql = "SELECT serviceinfo.* FROM serviceinfo LEFT JOIN serviceinfo_items ON serviceinfo.uid = serviceinfo_items.serviceinfo_uid WHERE serviceinfo_items.item_type = ? AND serviceinfo_items.item_uid IN (SELECT uid FROM ipinfo WHERE ip = ?)"; return $this->getModel()->query($sql, ['IP', $ip])->getResult(ServiceEntity::class); } return parent::findAllDatas($columns); } //기본 기능부분 //FieldForm관련용 public function getFormFieldOption(string $field, array $options = []): array { switch ($field) { case 'ownerinfo_uid': $options = $this->getClientService()->getEntities(); break; case 'user_uid': $options = $this->getUserService()->getEntities(); break; case 'codeinfo_uid': $options = $this->getCodeService()->getEntities(); break; case 'switchinfo_uid': $options = $this->getSwitchService()->getEntities(); break; default: $options = parent::getFormFieldOption($field, $options); break; } return $options; } //ItemType에 따른 FilterOption 설정용 public function getFilterOptionsByItemType(string $item_type): array { return $this->getServiceItemLinkService($item_type)->getEntities(); } //Service마다 ItemEntities 설정용 public function setItemEntitiesByService(ServiceEntity $entity): ServiceEntity { foreach (SERVICE_ITEM_TYPES as $item_type => $label) { $entity->setItemEntities( $item_type, $this->getServiceItemService()->getEntities([ 'serviceinfo_uid' => $entity->getPK(), 'item_type' => $item_type ]) ); } return $entity; } //interval을 기준으로 최근 신규 서비스정보 가져오기 final public function getEntitiesByNewService(int $interval, string $status = DEFAULTS['STATUS']): array { $where = sprintf("start_at >= NOW()-INTERVAL {$interval} DAY AND status = '%s'", $status); $entities = []; foreach ($this->getEntities($where) as $entity) { $entities[$entity->getPK()] = $this->setItemEntitiesByService($entity); }; return $entities; } //서비스 방식에 따른 서비스별 Count final public function getTotalCountsByType(): array { $sql = "SELECT type, COUNT(CASE WHEN location = 'default' THEN 1 END) AS chiba, COUNT(CASE WHEN location = 'tokyo' THEN 1 END) AS tokyo, COUNT(CASE WHEN location IN ('default', 'tokyo') THEN 1 END) AS total FROM serviceinfo GROUP BY type;"; $totalCounts = ['chiba_total' => 0, 'tokyo_total' => 0, 'all_total' => 0]; foreach ($this->getModel()->query($sql)->getResult() as $row) { $totalCounts[$row->type] = [ 'chiba' => $row->chiba, 'tokyo' => $row->tokyo, 'total' => $row->total, ]; $totalCounts['chiba_total'] += $row->chiba; $totalCounts['tokyo_total'] += $row->tokyo; } $totalCounts['all_total'] = $totalCounts['chiba_total'] + $totalCounts['tokyo_total']; return $totalCounts; } //다음 달로 결제일을 연장합니다. final public function extendBillingAt(string $billing_at, string $status): bool { $sql = "UPDATE serviceinfo SET billing_at = IF(DAY(billing_at) > DAY(LAST_DAY(billing_at)), LAST_DAY(DATE_ADD(billing_at, INTERVAL 1 MONTH)), DATE_ADD(billing_at, INTERVAL 1 MONTH) ) WHERE billing_at = ? AND status = ?"; return $this->getModel()->query($sql, [$billing_at, $status]); } public function create(array $formDatas, mixed $entity = null): ServiceEntity { //code의 경우 서비스중으로 설정작업 $this->getCodeService()->setStatus($formDatas['codeinfo_uid'], CodeEntity::STATUS_OCCUPIED); //switch의 경우 서비스중으로 설정작업 $this->getSwitchService()->setStatus($formDatas['switchinfo_uid'], SwitchEntity::STATUS_OCCUPIED); return parent::create($formDatas, $entity); } public function modify(mixed $entity, array $formDatas): ServiceEntity { //code가 기존과 다를경우 //toggle,batchjob의 경우 $formDatas에 code가 없을수도 있음 if (array_key_exists('codeinfo_uid', $formDatas) && $formDatas['codeinfo_uid'] !== $entity->getCodeUID()) { //기존 code의 경우 반환처리 $this->getCodeService()->setStatus($entity->getCodeUID(), CodeEntity::STATUS_AVAILABLE); //신규 설정된 code의 경우 서비스중 변경처리 $this->getCodeService()->setStatus($formDatas['codeinfo_uid'], CodeEntity::STATUS_OCCUPIED); } //switch가 기존과 다를경우 //toggle,batchjob의 경우 $formDatas에 switch가 없을수도 있음 if (array_key_exists('switchinfo_uid', $formDatas) && $formDatas['switchinfo_uid'] !== $entity->getSwitchUID()) { //기존 switch의 경우 반환처리 $this->getSwitchService()->setStatus($entity->getSwitchUID(), SwitchEntity::STATUS_AVAILABLE); //신규 설정된 switch의 경우 서비스중 변경처리 $this->getSwitchService()->setStatus($formDatas['switchinfo_uid'], SwitchEntity::STATUS_OCCUPIED); } //관리자가 바뀐경우 결제쪽에도 결제가 완료되지않은 것은 관리자를 변경해줘야함 if (array_key_exists('ownerinfo_uid', $formDatas) && $entity->getOwnerUID() !== intval($formDatas['ownerinfo_uid'])) { $this->getServicePaymentService()->modifyOwnerByService($entity, $formDatas['ownerinfo_uid']); } return parent::modify($entity, $formDatas); } public function delete(mixed $entity): ServiceEntity { //기존 code의 경우 반환처리 $this->getCodeService()->setStatus($entity->getCode(), CodeEntity::STATUS_AVAILABLE); //기존 switch의 경우 반환처리 $this->getSwitchService()->setStatus($entity->getCode(), SwitchEntity::STATUS_AVAILABLE); //Item들 삭제 foreach (SERVICE_ITEM_TYPES as $item_type => $label) { foreach ($entity->getItemEntities($item_type) as $itemEntity) { $this->getServiceItemService()->delete($itemEntity); } } return parent::delete($entity); } }