- Labor 모델 (BelongsToTenant, SoftDeletes)
- LaborController 7개 엔드포인트
- LaborService 비즈니스 로직
- FormRequest 4개 (Index/Store/Update/BulkDelete)
- 마이그레이션 및 라우트 등록
API: GET/POST /labor, GET/PUT/DELETE /labor/{id}, DELETE /labor/bulk, GET /labor/stats
Co-Authored-By: Claude <noreply@anthropic.com>
197 lines
4.9 KiB
PHP
197 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Labor;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
class LaborService extends Service
|
|
{
|
|
/**
|
|
* 노임 목록 조회
|
|
*/
|
|
public function index(array $params): LengthAwarePaginator
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
|
|
$size = (int) ($params['size'] ?? 20);
|
|
$search = trim((string) ($params['search'] ?? ''));
|
|
$category = $params['category'] ?? null;
|
|
$status = $params['status'] ?? null;
|
|
$startDate = $params['start_date'] ?? null;
|
|
$endDate = $params['end_date'] ?? null;
|
|
$sortOrder = $params['sort_order'] ?? 'latest';
|
|
|
|
$query = Labor::query()
|
|
->where('tenant_id', $tenantId);
|
|
|
|
// 검색어 필터
|
|
if ($search !== '') {
|
|
$query->search($search);
|
|
}
|
|
|
|
// 구분 필터
|
|
if ($category && $category !== 'all') {
|
|
$query->byCategory($category);
|
|
}
|
|
|
|
// 상태 필터
|
|
if ($status && $status !== 'all') {
|
|
$query->byStatus($status);
|
|
}
|
|
|
|
// 날짜 필터
|
|
if ($startDate) {
|
|
$query->whereDate('created_at', '>=', $startDate);
|
|
}
|
|
if ($endDate) {
|
|
$query->whereDate('created_at', '<=', $endDate);
|
|
}
|
|
|
|
// 정렬
|
|
if ($sortOrder === 'oldest') {
|
|
$query->orderBy('created_at', 'asc');
|
|
} else {
|
|
$query->orderByDesc('created_at');
|
|
}
|
|
|
|
return $query->paginate($size);
|
|
}
|
|
|
|
/**
|
|
* 노임 통계 조회
|
|
*/
|
|
public function stats(): array
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
|
|
$baseQuery = Labor::where('tenant_id', $tenantId);
|
|
|
|
$total = (clone $baseQuery)->count();
|
|
$active = (clone $baseQuery)->byStatus('사용')->count();
|
|
|
|
return [
|
|
'total' => $total,
|
|
'active' => $active,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 노임 상세 조회
|
|
*/
|
|
public function show(int $id): Labor
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
|
|
$labor = Labor::query()
|
|
->where('tenant_id', $tenantId)
|
|
->find($id);
|
|
|
|
if (! $labor) {
|
|
throw new NotFoundHttpException(__('error.not_found'));
|
|
}
|
|
|
|
return $labor;
|
|
}
|
|
|
|
/**
|
|
* 노임 등록
|
|
*/
|
|
public function store(array $data): Labor
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$userId = $this->apiUserId();
|
|
|
|
return DB::transaction(function () use ($data, $tenantId, $userId) {
|
|
$payload = array_merge($data, [
|
|
'tenant_id' => $tenantId,
|
|
'status' => $data['status'] ?? '사용',
|
|
'is_active' => true,
|
|
'created_by' => $userId,
|
|
]);
|
|
|
|
return Labor::create($payload);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 노임 수정
|
|
*/
|
|
public function update(int $id, array $data): Labor
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$userId = $this->apiUserId();
|
|
|
|
return DB::transaction(function () use ($id, $data, $tenantId, $userId) {
|
|
$labor = Labor::query()
|
|
->where('tenant_id', $tenantId)
|
|
->find($id);
|
|
|
|
if (! $labor) {
|
|
throw new NotFoundHttpException(__('error.not_found'));
|
|
}
|
|
|
|
$data['updated_by'] = $userId;
|
|
$labor->update($data);
|
|
$labor->refresh();
|
|
|
|
return $labor;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 노임 삭제 (soft delete)
|
|
*/
|
|
public function destroy(int $id): void
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$userId = $this->apiUserId();
|
|
|
|
DB::transaction(function () use ($id, $tenantId, $userId) {
|
|
$labor = Labor::query()
|
|
->where('tenant_id', $tenantId)
|
|
->find($id);
|
|
|
|
if (! $labor) {
|
|
throw new NotFoundHttpException(__('error.not_found'));
|
|
}
|
|
|
|
$labor->deleted_by = $userId;
|
|
$labor->save();
|
|
$labor->delete();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 노임 일괄 삭제 (soft delete)
|
|
*/
|
|
public function bulkDestroy(array $ids): int
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$userId = $this->apiUserId();
|
|
|
|
return DB::transaction(function () use ($ids, $tenantId, $userId) {
|
|
$labors = Labor::query()
|
|
->where('tenant_id', $tenantId)
|
|
->whereIn('id', $ids)
|
|
->get();
|
|
|
|
if ($labors->isEmpty()) {
|
|
throw new NotFoundHttpException(__('error.not_found'));
|
|
}
|
|
|
|
$deletedCount = 0;
|
|
foreach ($labors as $labor) {
|
|
$labor->deleted_by = $userId;
|
|
$labor->save();
|
|
$labor->delete();
|
|
$deletedCount++;
|
|
}
|
|
|
|
return $deletedCount;
|
|
});
|
|
}
|
|
}
|