feat: [bending] 절곡품 관리 API 완성 + 데이터 마이그레이션
- GuiderailModelController/Service/Resource: 가이드레일/케이스/하단마감재 통합 CRUD - item_category 필터 (GUIDERAIL_MODEL/SHUTTERBOX_MODEL/BOTTOMBAR_MODEL) - BendingItemResource: legacy_bending_num 노출 추가 - ApiKeyMiddleware: guiderail-models, files 화이트리스트 추가 - Swagger: BendingItemApi, GuiderailModelApi 문서 (케이스/하단마감재 필드 포함) - 마이그레이션 커맨드 5개: GuiderailImportLegacy, BendingProductImportLegacy, BendingImportImages, BendingModelImportImages, BendingModelImportAssemblyImages - 데이터: GR 20건 + SB 30건 + BB 10건 + 이미지 473건 R2 업로드
This commit is contained in:
120
app/Services/GuiderailModelService.php
Normal file
120
app/Services/GuiderailModelService.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Items\Item;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
class GuiderailModelService extends Service
|
||||
{
|
||||
private const CATEGORIES = ['GUIDERAIL_MODEL', 'SHUTTERBOX_MODEL', 'BOTTOMBAR_MODEL'];
|
||||
|
||||
public function list(array $params): LengthAwarePaginator
|
||||
{
|
||||
return Item::whereIn('item_category', self::CATEGORIES)
|
||||
->when($params['item_category'] ?? null, fn ($q, $v) => $q->where('item_category', $v))
|
||||
->when($params['item_sep'] ?? null, fn ($q, $v) => $q->where('options->item_sep', $v))
|
||||
->when($params['model_UA'] ?? null, fn ($q, $v) => $q->where('options->model_UA', $v))
|
||||
->when($params['check_type'] ?? null, fn ($q, $v) => $q->where('options->check_type', $v))
|
||||
->when($params['model_name'] ?? null, fn ($q, $v) => $q->where('options->model_name', $v))
|
||||
->when($params['search'] ?? null, fn ($q, $v) => $q->where(
|
||||
fn ($q2) => $q2
|
||||
->where('name', 'like', "%{$v}%")
|
||||
->orWhere('code', 'like', "%{$v}%")
|
||||
->orWhere('options->model_name', 'like', "%{$v}%")
|
||||
->orWhere('options->search_keyword', 'like', "%{$v}%")
|
||||
))
|
||||
->orderBy('code')
|
||||
->paginate($params['size'] ?? 50);
|
||||
}
|
||||
|
||||
public function filters(): array
|
||||
{
|
||||
$items = Item::whereIn('item_category', self::CATEGORIES)->select('options')->get();
|
||||
|
||||
return [
|
||||
'item_sep' => $items->pluck('options.item_sep')->filter()->unique()->sort()->values(),
|
||||
'model_UA' => $items->pluck('options.model_UA')->filter()->unique()->sort()->values(),
|
||||
'check_type' => $items->pluck('options.check_type')->filter()->unique()->sort()->values(),
|
||||
'model_name' => $items->pluck('options.model_name')->filter()->unique()->sort()->values(),
|
||||
'finishing_type' => $items->pluck('options.finishing_type')->filter()->unique()->sort()->values(),
|
||||
];
|
||||
}
|
||||
|
||||
public function find(int $id): Item
|
||||
{
|
||||
return Item::whereIn('item_category', self::CATEGORIES)->findOrFail($id);
|
||||
}
|
||||
|
||||
public function create(array $data): Item
|
||||
{
|
||||
$options = $this->buildOptions($data);
|
||||
|
||||
return Item::create([
|
||||
'tenant_id' => $this->tenantId(),
|
||||
'item_type' => 'FG',
|
||||
'item_category' => $data['item_category'] ?? 'GUIDERAIL_MODEL',
|
||||
'code' => $data['code'],
|
||||
'name' => $data['name'],
|
||||
'unit' => 'SET',
|
||||
'options' => $options,
|
||||
'is_active' => true,
|
||||
'created_by' => $this->apiUserId(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(int $id, array $data): Item
|
||||
{
|
||||
$item = Item::whereIn('item_category', self::CATEGORIES)->findOrFail($id);
|
||||
|
||||
if (isset($data['code'])) {
|
||||
$item->code = $data['code'];
|
||||
}
|
||||
if (isset($data['name'])) {
|
||||
$item->name = $data['name'];
|
||||
}
|
||||
|
||||
foreach (self::OPTION_KEYS as $key) {
|
||||
if (array_key_exists($key, $data)) {
|
||||
$item->setOption($key, $data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$item->updated_by = $this->apiUserId();
|
||||
$item->save();
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
public function delete(int $id): bool
|
||||
{
|
||||
$item = Item::whereIn('item_category', self::CATEGORIES)->findOrFail($id);
|
||||
$item->deleted_by = $this->apiUserId();
|
||||
$item->save();
|
||||
|
||||
return $item->delete();
|
||||
}
|
||||
|
||||
private function buildOptions(array $data): array
|
||||
{
|
||||
$options = [];
|
||||
foreach (self::OPTION_KEYS as $key) {
|
||||
if (isset($data[$key])) {
|
||||
$options[$key] = $data[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
private const OPTION_KEYS = [
|
||||
'model_name', 'check_type', 'rail_width', 'rail_length',
|
||||
'finishing_type', 'item_sep', 'model_UA', 'search_keyword',
|
||||
'author', 'memo', 'registration_date',
|
||||
'components', 'material_summary',
|
||||
// 케이스(SHUTTERBOX_MODEL) 전용
|
||||
'exit_direction', 'front_bottom_width', 'box_width', 'box_height',
|
||||
// 하단마감재(BOTTOMBAR_MODEL) 전용
|
||||
'bar_width', 'bar_height',
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user