Files
sam-manage/app/Services/Sales/BusinessCardRequestService.php
김보곤 85c7a55d00 feat: [business-card] 3단계 워크플로우 구현 (요청→제작의뢰→처리완료)
- 모델: STATUS_ORDERED 추가, markAsOrdered() 헬퍼
- 서비스: order(), getOrderedRequests() 추가
- 컨트롤러: order() 액션 추가
- 관리자 뷰: 좌측 신규요청 + 우측 제작중 + 하단 처리완료
- 파트너 뷰: 제작중(파란) 상태 뱃지 추가
- 라우트: POST business-cards/{id}/order 추가
2026-02-25 05:41:34 +09:00

138 lines
3.9 KiB
PHP

<?php
namespace App\Services\Sales;
use App\Models\Sales\BusinessCardRequest;
class BusinessCardRequestService
{
/**
* 뱃지용 대기 건수 (요청 + 제작의뢰)
*/
public function getPendingCount(): int
{
$tenantId = session('selected_tenant_id', 1);
return BusinessCardRequest::ofTenant($tenantId)
->whereIn('status', [BusinessCardRequest::STATUS_PENDING, BusinessCardRequest::STATUS_ORDERED])
->count();
}
/**
* 통계
*/
public function getStats(): array
{
$tenantId = session('selected_tenant_id', 1);
$base = BusinessCardRequest::ofTenant($tenantId);
return [
'pending' => (clone $base)->pending()->count(),
'ordered' => (clone $base)->ordered()->count(),
'processed_today' => (clone $base)->processed()
->whereDate('processed_at', today())
->count(),
'total' => (clone $base)->count(),
];
}
/**
* 신규 요청 목록
*/
public function getPendingRequests(?string $search = null, int $perPage = 20)
{
return $this->buildQuery(BusinessCardRequest::STATUS_PENDING, $search)
->with('requester')
->latest()
->paginate($perPage, ['*'], 'pending_page');
}
/**
* 제작의뢰 목록
*/
public function getOrderedRequests(?string $search = null, int $perPage = 20)
{
return $this->buildQuery(BusinessCardRequest::STATUS_ORDERED, $search)
->with(['requester', 'orderer'])
->latest('ordered_at')
->paginate($perPage, ['*'], 'ordered_page');
}
/**
* 처리완료 목록
*/
public function getProcessedRequests(?string $search = null, int $perPage = 20)
{
return $this->buildQuery(BusinessCardRequest::STATUS_PROCESSED, $search)
->with(['requester', 'processor'])
->latest('processed_at')
->paginate($perPage, ['*'], 'processed_page');
}
/**
* 내 신청 이력
*/
public function getMyRequests(int $userId, int $perPage = 20)
{
$tenantId = session('selected_tenant_id', 1);
return BusinessCardRequest::ofTenant($tenantId)
->where('user_id', $userId)
->with('processor')
->latest()
->paginate($perPage);
}
/**
* 신청 생성
*/
public function createRequest(array $data): BusinessCardRequest
{
$data['tenant_id'] = session('selected_tenant_id', 1);
$data['user_id'] = auth()->id();
$data['status'] = BusinessCardRequest::STATUS_PENDING;
return BusinessCardRequest::create($data);
}
/**
* 제작의뢰
*/
public function order(int $id): BusinessCardRequest
{
$tenantId = session('selected_tenant_id', 1);
$request = BusinessCardRequest::ofTenant($tenantId)->findOrFail($id);
$request->markAsOrdered(auth()->id());
return $request;
}
/**
* 처리 완료
*/
public function process(int $id, ?string $memo = null): BusinessCardRequest
{
$tenantId = session('selected_tenant_id', 1);
$request = BusinessCardRequest::ofTenant($tenantId)->findOrFail($id);
$request->markAsProcessed(auth()->id(), $memo);
return $request;
}
private function buildQuery(string $status, ?string $search)
{
$tenantId = session('selected_tenant_id', 1);
$query = BusinessCardRequest::ofTenant($tenantId)->where('status', $status);
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('name', 'like', "%{$search}%")
->orWhere('phone', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%");
});
}
return $query;
}
}