dbms/app/Services/Customer/ServiceService.php
2025-06-25 17:27:20 +09:00

233 lines
8.8 KiB
PHP

<?php
namespace App\Services\Customer;
use App\Entities\Customer\ServiceEntity;
use App\Entities\Equipment\CodeEntity;
use App\Entities\Equipment\Part\IpEntity;
use App\Models\Customer\ServiceModel;
use App\Services\Customer\ServiceItemService;
use App\Services\Equipment\CodeService;
use App\Services\Equipment\Part\IpService;
use App\Services\UserService;
class ServiceService extends CustomerService
{
private ?UserService $_userService = null;
private ?CodeService $_codeService = null;
private ?ServiceItemService $_serviceItemService = null;
private ?ServicePaymentService $_servicePaymentService = null;
private ?IpService $_ipService = null;
private ?string $_searchIP = null;
public function __construct(mixed $request = null)
{
parent::__construct($request);
$this->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",
"switch",
"code",
"raid",
"billing_at",
"start_at",
"status"
];
}
public function getFilterFields(): array
{
return ["clientinfo_uid", 'ownerinfo_uid', 'user_uid', 'type', 'location', 'switch', 'code', 'raid', 'status'];
}
public function getBatchJobFields(): array
{
return ['status'];
}
public function getIndexFields(): array
{
return ['clientinfo_uid', 'ownerinfo_uid', 'type', 'location', 'switch', 'code', 'raid', 'billing_at', 'start_at', 'updated_at', 'status', 'user_uid'];
}
public function getUSerService(): UserService
{
if (!$this->_userService) {
$this->_userService = new UserService($this->request);
}
return $this->_userService;
}
public function getCodeService(): CodeService
{
if (!$this->_codeService) {
$this->_codeService = new CodeService($this->request);
}
return $this->_codeService;
}
public function getServiceItemService(): ServiceItemService
{
if (!$this->_serviceItemService) {
$this->_serviceItemService = new ServiceItemService($this->request);
}
return $this->_serviceItemService;
}
public function getIpService(): IpService
{
if (!$this->_ipService) {
$this->_ipService = new IpService($this->request);
}
return $this->_ipService;
}
public function getServicePaymentService(): ServicePaymentService
{
if (!$this->_servicePaymentService) {
$this->_servicePaymentService = new ServicePaymentService($this->request);
}
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 'code':
$options = $this->getCodeService()->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['code'], CodeEntity::STATUS_OCCUPIED);
return parent::create($formDatas, $entity);
}
public function modify(mixed $entity, array $formDatas): ServiceEntity
{
//code가 기존과 다를경우 //toggle,batchjob의 경우 $formDatas에 code가 없을수도 있음
if (array_key_exists('code', $formDatas) && $formDatas['code'] !== $entity->getCode()) {
//기존 code의 경우 반환처리
$this->getCodeService()->setStatus($entity->getCode(), CodeEntity::STATUS_AVAILABLE);
//신규 설정된 coded의 경우 서비스중 변경처리
$this->getCodeService()->setStatus($formDatas['code'], CodeEntity::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);
//IP의 경우 반환 처리
foreach ($entity->getItemEntities("IP") as $itemEntity) {
$this->getIpService()->setStatus($itemEntity->getItemUID(), IpEntity::STATUS_AVAILABLE);
}
return parent::delete($entity);
}
}