dbmsv3/app/Processors/Customer/ServiceV1Processor.php
2025-10-24 10:35:12 +09:00

113 lines
4.0 KiB
PHP

<?php
namespace App\Processors\Customer;
use App\Entities\Customer\ServiceEntity;
use App\Entities\Equipment\ServerEntity;
use App\Entities\PaymentEntity;
use App\Services\Customer\ServiceService;
use App\Services\Equipment\ServerService;
use App\Services\MyLogService;
use App\Services\PaymentService;
use CodeIgniter\Database\BaseConnection;
use DateTimeImmutable;
use DateTimeZone;
use RuntimeException;
class ServiceV1Processor
{
public function __construct(
private BaseConnection $db,
private ServiceService $serviceService,
private ServerService $serverService,
private PaymentService $paymentService,
private MyLogService $logService,
) {}
/** 1) 서비스 생성 */
private function createService(array $formDatas): ServiceEntity
{
return $this->serviceService->getModel()->create($formDatas);
}
/** 2) 서버 연결 */
private function attachServer(ServiceEntity $entity): ServerEntity
{
$serverEntity = $this->serverService->getEntity($entity->getServerInfoUID());
if (!$serverEntity instanceof ServerEntity) {
throw new RuntimeException(sprintf(
'[%s]에 대한 서버정보를 찾을 수 없습니다.',
$entity->getServerInfoUID()
));
}
return $this->serverService->getModel()->modify($serverEntity, [
'clientinfo_uid' => $entity->getClientInfoUID(),
'serviceinfo_uid' => $entity->getPK(),
'status' => STATUS['OCCUPIED'],
]);
}
/** 3) 금액 계산 */
private function calculateAmount(ServiceEntity $entity, ServerEntity $serverEntity): ServiceEntity
{
$amount = $this->serviceService->getCalculatedAmount($entity, $serverEntity);
return $this->serviceService->getModel()->modify($entity, ['amount' => $amount]);
}
/** 4) 결제 생성 */
private function createPayment(ServiceEntity $entity, ServerEntity $serverEntity): PaymentEntity
{
$billingAt = new DateTimeImmutable($entity->getBillingAt() ?? 'now', new DateTimeZone('Asia/Tokyo'));
$title = sprintf('[%s/%s] %s 서비스비용', $serverEntity->getCode(), $serverEntity->getIP(), $billingAt->format('Y년 n월'));
return $this->paymentService->getModel()->create([
'clientinfo_uid' => $entity->getClientInfoUID(),
'serviceinfo_uid' => $entity->getPK(),
'serverinfo_uid' => $entity->getServerInfoUID(),
'title' => $title,
'amount' => $entity->getAmount(),
'billing' => PAYMENT['BILLING']['MONTH'],
'billing_at' => $billingAt->format('Y-m-d'),
]);
}
/** 5) 서비스 링크 갱신(FK 반영) */
private function updateLinks(ServiceEntity $entity, ServerEntity $serverEntity, PaymentEntity $paymentEntity): ServiceEntity
{
return $this->serviceService->getModel()->modify($entity, [
'serverinfo_id' => $serverEntity->getPK(),
'payment_uid' => $paymentEntity->getPK(),
]);
}
/** 6) 로그 */
private function stepLog(ServiceEntity $entity): void
{
$this->logService->create([
'title' => sprintf('[%s] 서비스정보 추가', $entity->getCustomTitle()),
'status' => $entity->getStatus(),
]);
}
/** 최종 결과만 필요할 때 */
public function create(array $formDatas): ServiceEntity
{
$this->db->transStart();
if (!isset($formDatas['serverinfo_uid'])) {
throw new RuntimeException('서버가 지정되지 않았습니다.');
}
// 1) 서비스 생성
$entity = $this->createService($formDatas);
// 2) 서버 연결
$serverEntity = $this->attachServer($entity);
// 3) 금액 계산
$entity = $this->calculateAmount($entity, $serverEntity);
// 4) 결제 생성
$paymentEntity = $this->createPayment($entity, $serverEntity);
// 5) 서비스 링크 갱신(FK 반영)
$entity = $this->updateLinks($entity, $serverEntity, $paymentEntity);
// 6) 로그 (필요 시 이벤트로 대체)
$this->stepLog($entity);
$this->db->transComplete();
if ($this->db->transStatus() === false) {
throw new RuntimeException('트랜잭션 실패');
}
return $entity;
}
}