feat: 품목 마스터 소스 매핑 기능 추가
- ItemField 모델: 소스 매핑 컬럼 추가 (source_table, source_column 등) - ItemPage 모델: source_table 컬럼 추가 - ItemDataService: 동적 데이터 조회 서비스 - ItemMasterApi Swagger 업데이트 - ItemTypeSeeder: 품목 유형 시더 - 스펙 문서: ITEM_MASTER_FIELD_INTEGRATION_PLAN.md
This commit is contained in:
@@ -35,6 +35,11 @@ class ItemField extends Model
|
|||||||
'created_by',
|
'created_by',
|
||||||
'updated_by',
|
'updated_by',
|
||||||
'deleted_by',
|
'deleted_by',
|
||||||
|
// 내부용 매핑 컬럼
|
||||||
|
'source_table',
|
||||||
|
'source_column',
|
||||||
|
'storage_type',
|
||||||
|
'json_path',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
@@ -54,9 +59,17 @@ class ItemField extends Model
|
|||||||
'locked_at' => 'datetime',
|
'locked_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API 응답에서 제외할 컬럼 (내부용)
|
||||||
|
*/
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'deleted_by',
|
'deleted_by',
|
||||||
'deleted_at',
|
'deleted_at',
|
||||||
|
// 내부용 매핑 컬럼 - API 응답에서 제외
|
||||||
|
'source_table',
|
||||||
|
'source_column',
|
||||||
|
'storage_type',
|
||||||
|
'json_path',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,4 +108,28 @@ public function allParentRelationships()
|
|||||||
return EntityRelationship::where('child_type', EntityRelationship::TYPE_FIELD)
|
return EntityRelationship::where('child_type', EntityRelationship::TYPE_FIELD)
|
||||||
->where('child_id', $this->id);
|
->where('child_id', $this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 시스템 필드 여부 확인 (DB 컬럼과 매핑된 필드)
|
||||||
|
*/
|
||||||
|
public function isSystemField(): bool
|
||||||
|
{
|
||||||
|
return ! is_null($this->source_table) && ! is_null($this->source_column);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 컬럼 저장 방식 여부 확인
|
||||||
|
*/
|
||||||
|
public function isColumnStorage(): bool
|
||||||
|
{
|
||||||
|
return $this->storage_type === 'column';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON 저장 방식 여부 확인
|
||||||
|
*/
|
||||||
|
public function isJsonStorage(): bool
|
||||||
|
{
|
||||||
|
return $this->storage_type === 'json';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class ItemPage extends Model
|
|||||||
'group_id',
|
'group_id',
|
||||||
'page_name',
|
'page_name',
|
||||||
'item_type',
|
'item_type',
|
||||||
|
'source_table', // 실제 저장 테이블명 (products, materials 등)
|
||||||
'absolute_path',
|
'absolute_path',
|
||||||
'is_active',
|
'is_active',
|
||||||
'created_by',
|
'created_by',
|
||||||
@@ -95,4 +96,33 @@ public function allRelationships()
|
|||||||
->where('parent_type', EntityRelationship::TYPE_PAGE)
|
->where('parent_type', EntityRelationship::TYPE_PAGE)
|
||||||
->orderBy('order_no');
|
->orderBy('order_no');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* source_table에 해당하는 모델 클래스명 반환
|
||||||
|
*/
|
||||||
|
public function getTargetModelClass(): ?string
|
||||||
|
{
|
||||||
|
$mapping = [
|
||||||
|
'products' => \App\Models\Product::class,
|
||||||
|
'materials' => \App\Models\Material::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $mapping[$this->source_table] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 제품 페이지인지 확인
|
||||||
|
*/
|
||||||
|
public function isProductPage(): bool
|
||||||
|
{
|
||||||
|
return $this->source_table === 'products';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 자재 페이지인지 확인
|
||||||
|
*/
|
||||||
|
public function isMaterialPage(): bool
|
||||||
|
{
|
||||||
|
return $this->source_table === 'materials';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
174
app/Services/ItemMaster/ItemDataService.php
Normal file
174
app/Services/ItemMaster/ItemDataService.php
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\ItemMaster;
|
||||||
|
|
||||||
|
use App\Models\ItemMaster\ItemField;
|
||||||
|
use App\Services\Service;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ItemDataService extends Service
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 필드 값을 적절한 테이블/컬럼에 저장
|
||||||
|
*
|
||||||
|
* @param string $sourceTable 대상 테이블 (products, materials 등)
|
||||||
|
* @param array $fieldValues [field_id => value] 형태
|
||||||
|
* @param int|null $recordId 수정 시 레코드 ID
|
||||||
|
* @return array 저장된 데이터
|
||||||
|
*/
|
||||||
|
public function saveData(string $sourceTable, array $fieldValues, ?int $recordId = null): array
|
||||||
|
{
|
||||||
|
// 해당 테이블의 필드 매핑 정보 조회
|
||||||
|
$fields = ItemField::where('tenant_id', $this->tenantId())
|
||||||
|
->where('source_table', $sourceTable)
|
||||||
|
->get()
|
||||||
|
->keyBy('id');
|
||||||
|
|
||||||
|
$columnData = []; // DB 컬럼 직접 저장
|
||||||
|
$jsonData = []; // JSON (attributes/options) 저장
|
||||||
|
|
||||||
|
foreach ($fieldValues as $fieldId => $value) {
|
||||||
|
$field = $fields->get($fieldId);
|
||||||
|
|
||||||
|
if (! $field) {
|
||||||
|
// 시스템 필드가 아닌 커스텀 필드
|
||||||
|
$customField = ItemField::find($fieldId);
|
||||||
|
if ($customField) {
|
||||||
|
$jsonPath = $customField->json_path ?? "attributes.{$customField->field_key}";
|
||||||
|
data_set($jsonData, $jsonPath, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($field->isColumnStorage()) {
|
||||||
|
// DB 컬럼에 직접 저장
|
||||||
|
$columnData[$field->source_column] = $this->castValue($value, $field);
|
||||||
|
} else {
|
||||||
|
// JSON 필드에 저장
|
||||||
|
$jsonPath = $field->json_path ?? "attributes.{$field->field_key}";
|
||||||
|
data_set($jsonData, $jsonPath, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON 데이터 병합
|
||||||
|
if (! empty($jsonData['attributes'])) {
|
||||||
|
$columnData['attributes'] = json_encode($jsonData['attributes']);
|
||||||
|
}
|
||||||
|
if (! empty($jsonData['options'])) {
|
||||||
|
$columnData['options'] = json_encode($jsonData['options']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 공통 컬럼 추가
|
||||||
|
$columnData['tenant_id'] = $this->tenantId();
|
||||||
|
$columnData['updated_by'] = $this->apiUserId();
|
||||||
|
|
||||||
|
if ($recordId) {
|
||||||
|
// 수정
|
||||||
|
DB::table($sourceTable)
|
||||||
|
->where('tenant_id', $this->tenantId())
|
||||||
|
->where('id', $recordId)
|
||||||
|
->update($columnData);
|
||||||
|
|
||||||
|
return array_merge(['id' => $recordId], $columnData);
|
||||||
|
} else {
|
||||||
|
// 생성
|
||||||
|
$columnData['created_by'] = $this->apiUserId();
|
||||||
|
$id = DB::table($sourceTable)->insertGetId($columnData);
|
||||||
|
|
||||||
|
return array_merge(['id' => $id], $columnData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 필드 타입에 따른 값 변환
|
||||||
|
*/
|
||||||
|
private function castValue($value, ItemField $field)
|
||||||
|
{
|
||||||
|
return match ($field->field_type) {
|
||||||
|
'number' => is_numeric($value) ? (float) $value : null,
|
||||||
|
'checkbox' => filter_var($value, FILTER_VALIDATE_BOOLEAN),
|
||||||
|
'date' => $value ? date('Y-m-d', strtotime($value)) : null,
|
||||||
|
default => $value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 레코드 조회 시 필드 매핑 적용
|
||||||
|
*
|
||||||
|
* @param string $sourceTable 대상 테이블 (products, materials 등)
|
||||||
|
* @param int $recordId 레코드 ID
|
||||||
|
* @return array 필드 ID => 값 형태의 데이터
|
||||||
|
*/
|
||||||
|
public function getData(string $sourceTable, int $recordId): array
|
||||||
|
{
|
||||||
|
$record = DB::table($sourceTable)
|
||||||
|
->where('tenant_id', $this->tenantId())
|
||||||
|
->where('id', $recordId)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (! $record) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 필드 매핑 정보 조회
|
||||||
|
$fields = ItemField::where('tenant_id', $this->tenantId())
|
||||||
|
->where('source_table', $sourceTable)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
$attributes = json_decode($record->attributes ?? '{}', true);
|
||||||
|
$options = json_decode($record->options ?? '{}', true);
|
||||||
|
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
if ($field->isColumnStorage()) {
|
||||||
|
$result[$field->id] = $record->{$field->source_column} ?? null;
|
||||||
|
} else {
|
||||||
|
$jsonPath = $field->json_path ?? "attributes.{$field->field_key}";
|
||||||
|
$result[$field->id] = data_get(
|
||||||
|
['attributes' => $attributes, 'options' => $options],
|
||||||
|
$jsonPath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 페이지 기반으로 레코드 저장
|
||||||
|
*
|
||||||
|
* @param int $pageId ItemPage ID
|
||||||
|
* @param array $fieldValues [field_id => value] 형태
|
||||||
|
* @param int|null $recordId 수정 시 레코드 ID
|
||||||
|
* @return array 저장된 데이터
|
||||||
|
*/
|
||||||
|
public function saveDataByPage(int $pageId, array $fieldValues, ?int $recordId = null): array
|
||||||
|
{
|
||||||
|
$page = \App\Models\ItemMaster\ItemPage::find($pageId);
|
||||||
|
|
||||||
|
if (! $page || ! $page->source_table) {
|
||||||
|
throw new \InvalidArgumentException("Invalid page or source_table not defined for page: {$pageId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->saveData($page->source_table, $fieldValues, $recordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 페이지 기반으로 레코드 조회
|
||||||
|
*
|
||||||
|
* @param int $pageId ItemPage ID
|
||||||
|
* @param int $recordId 레코드 ID
|
||||||
|
* @return array 필드 ID => 값 형태의 데이터
|
||||||
|
*/
|
||||||
|
public function getDataByPage(int $pageId, int $recordId): array
|
||||||
|
{
|
||||||
|
$page = \App\Models\ItemMaster\ItemPage::find($pageId);
|
||||||
|
|
||||||
|
if (! $page || ! $page->source_table) {
|
||||||
|
throw new \InvalidArgumentException("Invalid page or source_table not defined for page: {$pageId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getData($page->source_table, $recordId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
* @OA\Schema(
|
* @OA\Schema(
|
||||||
* schema="ItemSection",
|
* schema="ItemSection",
|
||||||
* type="object",
|
* type="object",
|
||||||
* description="독립 엔티티 - 관계는 entity_relationships로 관리",
|
* description="엔티티 - 관계는 entity_relationships로 관리",
|
||||||
*
|
*
|
||||||
* @OA\Property(property="id", type="integer", example=1),
|
* @OA\Property(property="id", type="integer", example=1),
|
||||||
* @OA\Property(property="tenant_id", type="integer", example=1),
|
* @OA\Property(property="tenant_id", type="integer", example=1),
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
* @OA\Schema(
|
* @OA\Schema(
|
||||||
* schema="ItemField",
|
* schema="ItemField",
|
||||||
* type="object",
|
* type="object",
|
||||||
* description="독립 엔티티 - 관계는 entity_relationships로 관리",
|
* description="엔티티 - 관계는 entity_relationships로 관리",
|
||||||
*
|
*
|
||||||
* @OA\Property(property="id", type="integer", example=1),
|
* @OA\Property(property="id", type="integer", example=1),
|
||||||
* @OA\Property(property="tenant_id", type="integer", example=1),
|
* @OA\Property(property="tenant_id", type="integer", example=1),
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
* @OA\Schema(
|
* @OA\Schema(
|
||||||
* schema="ItemBomItem",
|
* schema="ItemBomItem",
|
||||||
* type="object",
|
* type="object",
|
||||||
* description="독립 엔티티 - 관계는 entity_relationships로 관리",
|
* description="엔티티 - 관계는 entity_relationships로 관리",
|
||||||
*
|
*
|
||||||
* @OA\Property(property="id", type="integer", example=1),
|
* @OA\Property(property="id", type="integer", example=1),
|
||||||
* @OA\Property(property="tenant_id", type="integer", example=1),
|
* @OA\Property(property="tenant_id", type="integer", example=1),
|
||||||
@@ -190,7 +190,7 @@
|
|||||||
* required={"title","type"},
|
* required={"title","type"},
|
||||||
*
|
*
|
||||||
* @OA\Property(property="group_id", type="integer", nullable=true, example=1, description="계층번호"),
|
* @OA\Property(property="group_id", type="integer", nullable=true, example=1, description="계층번호"),
|
||||||
* @OA\Property(property="title", type="string", maxLength=255, example="독립 섹션"),
|
* @OA\Property(property="title", type="string", maxLength=255, example="섹션"),
|
||||||
* @OA\Property(property="type", type="string", enum={"fields","bom"}, example="fields"),
|
* @OA\Property(property="type", type="string", enum={"fields","bom"}, example="fields"),
|
||||||
* @OA\Property(property="is_template", type="boolean", example=false),
|
* @OA\Property(property="is_template", type="boolean", example=false),
|
||||||
* @OA\Property(property="is_default", type="boolean", example=false),
|
* @OA\Property(property="is_default", type="boolean", example=false),
|
||||||
@@ -415,7 +415,7 @@
|
|||||||
* @OA\Property(
|
* @OA\Property(
|
||||||
* property="sections",
|
* property="sections",
|
||||||
* type="array",
|
* type="array",
|
||||||
* description="모든 독립 섹션 목록 (재사용 가능)",
|
* description="모든 섹션 목록 (재사용 가능)",
|
||||||
*
|
*
|
||||||
* @OA\Items(ref="#/components/schemas/ItemSection")
|
* @OA\Items(ref="#/components/schemas/ItemSection")
|
||||||
* ),
|
* ),
|
||||||
@@ -423,7 +423,7 @@
|
|||||||
* @OA\Property(
|
* @OA\Property(
|
||||||
* property="fields",
|
* property="fields",
|
||||||
* type="array",
|
* type="array",
|
||||||
* description="모든 독립 필드 목록 (재사용 가능)",
|
* description="모든 필드 목록 (재사용 가능)",
|
||||||
*
|
*
|
||||||
* @OA\Items(ref="#/components/schemas/ItemField")
|
* @OA\Items(ref="#/components/schemas/ItemField")
|
||||||
* ),
|
* ),
|
||||||
@@ -445,6 +445,10 @@
|
|||||||
*/
|
*/
|
||||||
class ItemMasterApi
|
class ItemMasterApi
|
||||||
{
|
{
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
// 초기화
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Get(
|
* @OA\Get(
|
||||||
* path="/api/v1/item-master/init",
|
* path="/api/v1/item-master/init",
|
||||||
@@ -466,6 +470,253 @@ class ItemMasterApi
|
|||||||
*/
|
*/
|
||||||
public function init() {}
|
public function init() {}
|
||||||
|
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
// 필드 (Fields)
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/item-master/fields",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 목록 조회",
|
||||||
|
* description="섹션과 연결되지 않은 필드 목록을 조회합니다.",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="조회 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/ItemField")))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function indexFields() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/item-master/fields",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 생성",
|
||||||
|
* description="섹션과 연결되지 않은 필드를 생성합니다.",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentFieldStoreRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="생성 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function storeIndependentField() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/item-master/sections/{sectionId}/fields",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 생성 (섹션 연결)",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemFieldStoreRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="생성 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function storeFields() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/item-master/fields/{id}",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 수정",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemFieldUpdateRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="수정 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function updateFields() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/v1/item-master/fields/{id}",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 삭제",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
||||||
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function destroyFields() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/item-master/sections/{sectionId}/fields/reorder",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 순서 변경",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ReorderRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="순서 변경 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
||||||
|
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function reorderFields() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/item-master/fields/{id}/clone",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 복제",
|
||||||
|
* description="기존 필드를 복제하여 새 필드를 생성합니다.",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="id", in="path", required=true, description="복제할 필드 ID", @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="복제 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function cloneField() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/item-master/fields/{id}/usage",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="필드 사용처 조회",
|
||||||
|
* description="필드가 어떤 섹션/페이지에 연결되어 있는지 조회합니다.",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="id", in="path", required=true, description="필드 ID", @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="조회 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/FieldUsageResponse"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function getFieldUsage() {}
|
||||||
|
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
// 단위 (Unit Options)
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/item-master/unit-options",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="단위 옵션 목록",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="조회 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/UnitOption")))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function indexUnitOptions() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/item-master/unit-options",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="단위 옵션 생성",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/UnitOptionStoreRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="생성 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/UnitOption"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function storeUnitOptions() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/v1/item-master/unit-options/{id}",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="단위 옵션 삭제",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
||||||
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function destroyUnitOptions() {}
|
||||||
|
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
// 페이지 (Pages)
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Get(
|
* @OA\Get(
|
||||||
* path="/api/v1/item-master/pages",
|
* path="/api/v1/item-master/pages",
|
||||||
@@ -553,12 +804,16 @@ public function updatePages() {}
|
|||||||
*/
|
*/
|
||||||
public function destroyPages() {}
|
public function destroyPages() {}
|
||||||
|
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
// 섹션 (Sections)
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Get(
|
* @OA\Get(
|
||||||
* path="/api/v1/item-master/sections",
|
* path="/api/v1/item-master/sections",
|
||||||
* tags={"ItemMaster"},
|
* tags={"ItemMaster"},
|
||||||
* summary="독립 섹션 목록 조회",
|
* summary="섹션 목록 조회",
|
||||||
* description="페이지와 연결되지 않은 독립 섹션 목록을 조회합니다. is_template 파라미터로 템플릿 필터링이 가능합니다.",
|
* description="페이지와 연결되지 않은 섹션 목록을 조회합니다. is_template 파라미터로 템플릿 필터링이 가능합니다.",
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
*
|
*
|
||||||
* @OA\Parameter(name="is_template", in="query", description="템플릿 여부 필터", @OA\Schema(type="boolean")),
|
* @OA\Parameter(name="is_template", in="query", description="템플릿 여부 필터", @OA\Schema(type="boolean")),
|
||||||
@@ -581,8 +836,8 @@ public function indexSections() {}
|
|||||||
* @OA\Post(
|
* @OA\Post(
|
||||||
* path="/api/v1/item-master/sections",
|
* path="/api/v1/item-master/sections",
|
||||||
* tags={"ItemMaster"},
|
* tags={"ItemMaster"},
|
||||||
* summary="독립 섹션 생성",
|
* summary="섹션 생성",
|
||||||
* description="페이지와 연결되지 않은 독립 섹션을 생성합니다.",
|
* description="페이지와 연결되지 않은 섹션을 생성합니다.",
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
*
|
*
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentSectionStoreRequest")),
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentSectionStoreRequest")),
|
||||||
@@ -601,194 +856,6 @@ public function indexSections() {}
|
|||||||
*/
|
*/
|
||||||
public function storeIndependentSection() {}
|
public function storeIndependentSection() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Post(
|
|
||||||
* path="/api/v1/item-master/sections/{id}/clone",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="섹션 복제",
|
|
||||||
* description="기존 섹션을 복제하여 새 독립 섹션을 생성합니다. 하위 필드와 BOM 항목도 함께 복제됩니다.",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, description="복제할 섹션 ID", @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="복제 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemSection"))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function cloneSection() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Get(
|
|
||||||
* path="/api/v1/item-master/sections/{id}/usage",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="섹션 사용처 조회",
|
|
||||||
* description="섹션이 어떤 페이지에 연결되어 있는지 조회합니다 (entity_relationships 기반).",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, description="섹션 ID", @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="조회 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/SectionUsageResponse"))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function getSectionUsage() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Get(
|
|
||||||
* path="/api/v1/item-master/fields",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="독립 필드 목록 조회",
|
|
||||||
* description="섹션과 연결되지 않은 독립 필드 목록을 조회합니다.",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="조회 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/ItemField")))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function indexFields() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Post(
|
|
||||||
* path="/api/v1/item-master/fields",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="독립 필드 생성",
|
|
||||||
* description="섹션과 연결되지 않은 독립 필드를 생성합니다.",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentFieldStoreRequest")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="생성 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function storeIndependentField() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Post(
|
|
||||||
* path="/api/v1/item-master/fields/{id}/clone",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="필드 복제",
|
|
||||||
* description="기존 필드를 복제하여 새 독립 필드를 생성합니다.",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, description="복제할 필드 ID", @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="복제 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function cloneField() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Get(
|
|
||||||
* path="/api/v1/item-master/fields/{id}/usage",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="필드 사용처 조회",
|
|
||||||
* description="필드가 어떤 섹션/페이지에 연결되어 있는지 조회합니다.",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, description="필드 ID", @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="조회 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/FieldUsageResponse"))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function getFieldUsage() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Get(
|
|
||||||
* path="/api/v1/item-master/bom-items",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="독립 BOM 목록 조회",
|
|
||||||
* description="섹션과 연결되지 않은 독립 BOM 항목 목록을 조회합니다.",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="조회 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/ItemBomItem")))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function indexBomItems() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Post(
|
|
||||||
* path="/api/v1/item-master/bom-items",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="독립 BOM 생성",
|
|
||||||
* description="섹션과 연결되지 않은 독립 BOM 항목을 생성합니다.",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentBomItemStoreRequest")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="생성 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function storeIndependentBomItem() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Post(
|
* @OA\Post(
|
||||||
* path="/api/v1/item-master/pages/{pageId}/sections",
|
* path="/api/v1/item-master/pages/{pageId}/sections",
|
||||||
@@ -874,150 +941,55 @@ public function reorderSections() {}
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Post(
|
* @OA\Post(
|
||||||
* path="/api/v1/item-master/sections/{sectionId}/fields",
|
* path="/api/v1/item-master/sections/{id}/clone",
|
||||||
* tags={"ItemMaster"},
|
* tags={"ItemMaster"},
|
||||||
* summary="필드 생성",
|
* summary="섹션 복제",
|
||||||
|
* description="기존 섹션을 복제하여 새 섹션을 생성합니다. 하위 필드와 BOM 항목도 함께 복제됩니다.",
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
*
|
*
|
||||||
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
|
* @OA\Parameter(name="id", in="path", required=true, description="복제할 섹션 ID", @OA\Schema(type="integer")),
|
||||||
*
|
*
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemFieldStoreRequest")),
|
* @OA\Response(response=200, description="복제 성공",
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="생성 성공",
|
|
||||||
*
|
*
|
||||||
* @OA\JsonContent(allOf={
|
* @OA\JsonContent(allOf={
|
||||||
*
|
*
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemSection"))
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function storeFields() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Put(
|
|
||||||
* path="/api/v1/item-master/fields/{id}",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="필드 수정",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemFieldUpdateRequest")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="수정 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemField"))
|
|
||||||
* })
|
* })
|
||||||
* ),
|
* ),
|
||||||
*
|
*
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
public function updateFields() {}
|
public function cloneSection() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Delete(
|
* @OA\Get(
|
||||||
* path="/api/v1/item-master/fields/{id}",
|
* path="/api/v1/item-master/sections/{id}/usage",
|
||||||
* tags={"ItemMaster"},
|
* tags={"ItemMaster"},
|
||||||
* summary="필드 삭제",
|
* summary="섹션 사용처 조회",
|
||||||
|
* description="섹션이 어떤 페이지에 연결되어 있는지 조회합니다 (entity_relationships 기반).",
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
*
|
*
|
||||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
* @OA\Parameter(name="id", in="path", required=true, description="섹션 ID", @OA\Schema(type="integer")),
|
||||||
*
|
*
|
||||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
* @OA\Response(response=200, description="조회 성공",
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function destroyFields() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Put(
|
|
||||||
* path="/api/v1/item-master/sections/{sectionId}/fields/reorder",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="필드 순서 변경",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ReorderRequest")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="순서 변경 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
|
||||||
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function reorderFields() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Post(
|
|
||||||
* path="/api/v1/item-master/sections/{sectionId}/bom-items",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="BOM 항목 생성",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemBomItemStoreRequest")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="생성 성공",
|
|
||||||
*
|
*
|
||||||
* @OA\JsonContent(allOf={
|
* @OA\JsonContent(allOf={
|
||||||
*
|
*
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/SectionUsageResponse"))
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function storeBomItems() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Put(
|
|
||||||
* path="/api/v1/item-master/bom-items/{id}",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="BOM 항목 수정",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemBomItemUpdateRequest")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="수정 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
|
|
||||||
* })
|
* })
|
||||||
* ),
|
* ),
|
||||||
*
|
*
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
public function updateBomItems() {}
|
public function getSectionUsage() {}
|
||||||
|
|
||||||
/**
|
// ────────────────────────────────────────────────────────────────────────
|
||||||
* @OA\Delete(
|
// 섹션 템플릿 (Section Templates)
|
||||||
* path="/api/v1/item-master/bom-items/{id}",
|
// ────────────────────────────────────────────────────────────────────────
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="BOM 항목 삭제",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function destroyBomItems() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Get(
|
* @OA\Get(
|
||||||
@@ -1103,6 +1075,125 @@ public function updateSectionTemplates() {}
|
|||||||
*/
|
*/
|
||||||
public function destroySectionTemplates() {}
|
public function destroySectionTemplates() {}
|
||||||
|
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
// BOM
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/item-master/bom-items",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="BOM 목록 조회",
|
||||||
|
* description="섹션과 연결되지 않은 BOM 항목 목록을 조회합니다.",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="조회 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/ItemBomItem")))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function indexBomItems() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/item-master/bom-items",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="BOM 생성",
|
||||||
|
* description="섹션과 연결되지 않은 BOM 항목을 생성합니다.",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/IndependentBomItemStoreRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="생성 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function storeIndependentBomItem() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/item-master/sections/{sectionId}/bom-items",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="BOM 항목 생성 (섹션 연결)",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="sectionId", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemBomItemStoreRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="생성 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function storeBomItems() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/item-master/bom-items/{id}",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="BOM 항목 수정",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/ItemBomItemUpdateRequest")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="수정 성공",
|
||||||
|
*
|
||||||
|
* @OA\JsonContent(allOf={
|
||||||
|
*
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
||||||
|
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/ItemBomItem"))
|
||||||
|
* })
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function updateBomItems() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/v1/item-master/bom-items/{id}",
|
||||||
|
* tags={"ItemMaster"},
|
||||||
|
* summary="BOM 항목 삭제",
|
||||||
|
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||||
|
*
|
||||||
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||||
|
*
|
||||||
|
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
||||||
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function destroyBomItems() {}
|
||||||
|
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
// 커스텀 탭 (Custom Tabs)
|
||||||
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @OA\Get(
|
* @OA\Get(
|
||||||
* path="/api/v1/item-master/custom-tabs",
|
* path="/api/v1/item-master/custom-tabs",
|
||||||
@@ -1201,63 +1292,4 @@ public function destroyCustomTabs() {}
|
|||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
public function reorderCustomTabs() {}
|
public function reorderCustomTabs() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Get(
|
|
||||||
* path="/api/v1/item-master/unit-options",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="단위 옵션 목록",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="조회 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/UnitOption")))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function indexUnitOptions() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Post(
|
|
||||||
* path="/api/v1/item-master/unit-options",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="단위 옵션 생성",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/UnitOptionStoreRequest")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="생성 성공",
|
|
||||||
*
|
|
||||||
* @OA\JsonContent(allOf={
|
|
||||||
*
|
|
||||||
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
||||||
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/UnitOption"))
|
|
||||||
* })
|
|
||||||
* ),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function storeUnitOptions() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @OA\Delete(
|
|
||||||
* path="/api/v1/item-master/unit-options/{id}",
|
|
||||||
* tags={"ItemMaster"},
|
|
||||||
* summary="단위 옵션 삭제",
|
|
||||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
|
||||||
*
|
|
||||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
||||||
*
|
|
||||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
|
||||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function destroyUnitOptions() {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('item_pages', function (Blueprint $table) {
|
||||||
|
// source_table 컬럼 추가
|
||||||
|
$table->string('source_table', 100)
|
||||||
|
->nullable()
|
||||||
|
->after('item_type')
|
||||||
|
->comment('실제 저장 테이블명 (products, materials 등)');
|
||||||
|
|
||||||
|
// 인덱스
|
||||||
|
$table->index('source_table', 'idx_source_table');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 기존 데이터 업데이트: item_type 기반으로 source_table 설정
|
||||||
|
DB::table('item_pages')
|
||||||
|
->whereIn('item_type', ['FG', 'PT'])
|
||||||
|
->update(['source_table' => 'products']);
|
||||||
|
|
||||||
|
DB::table('item_pages')
|
||||||
|
->whereIn('item_type', ['SM', 'RM', 'CS'])
|
||||||
|
->update(['source_table' => 'materials']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('item_pages', function (Blueprint $table) {
|
||||||
|
$table->dropIndex('idx_source_table');
|
||||||
|
$table->dropColumn('source_table');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('item_fields', function (Blueprint $table) {
|
||||||
|
// 내부용 매핑 컬럼 (API 응답에서 제외)
|
||||||
|
$table->string('source_table', 100)
|
||||||
|
->nullable()
|
||||||
|
->after('properties')
|
||||||
|
->comment('내부용: 원본 테이블명 (products, materials 등)');
|
||||||
|
|
||||||
|
$table->string('source_column', 100)
|
||||||
|
->nullable()
|
||||||
|
->after('source_table')
|
||||||
|
->comment('내부용: 원본 컬럼명 (code, name 등)');
|
||||||
|
|
||||||
|
$table->enum('storage_type', ['column', 'json'])
|
||||||
|
->default('json')
|
||||||
|
->after('source_column')
|
||||||
|
->comment('내부용: 저장방식 (column=DB컬럼, json=attributes/options)');
|
||||||
|
|
||||||
|
$table->string('json_path', 200)
|
||||||
|
->nullable()
|
||||||
|
->after('storage_type')
|
||||||
|
->comment('내부용: JSON 저장 경로 (예: attributes.custom_size)');
|
||||||
|
|
||||||
|
// 인덱스
|
||||||
|
$table->index(['source_table', 'source_column'], 'idx_source_mapping');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('item_fields', function (Blueprint $table) {
|
||||||
|
$table->dropIndex('idx_source_mapping');
|
||||||
|
$table->dropColumn(['source_table', 'source_column', 'storage_type', 'json_path']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
45
database/seeders/ItemTypeSeeder.php
Normal file
45
database/seeders/ItemTypeSeeder.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ItemTypeSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
* common_codes 테이블에 item_type 그룹 데이터 시딩
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$tenantId = 1; // 기본 테넌트
|
||||||
|
|
||||||
|
// code_group = 'item_type' (컬럼명과 동일하게!)
|
||||||
|
$itemTypes = [
|
||||||
|
['code_group' => 'item_type', 'code' => 'FG', 'name' => '완제품', 'tenant_id' => $tenantId],
|
||||||
|
['code_group' => 'item_type', 'code' => 'PT', 'name' => '반제품', 'tenant_id' => $tenantId],
|
||||||
|
['code_group' => 'item_type', 'code' => 'SM', 'name' => '부자재', 'tenant_id' => $tenantId],
|
||||||
|
['code_group' => 'item_type', 'code' => 'RM', 'name' => '원자재', 'tenant_id' => $tenantId],
|
||||||
|
['code_group' => 'item_type', 'code' => 'CS', 'name' => '소모품', 'tenant_id' => $tenantId],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($itemTypes as $index => $item) {
|
||||||
|
DB::table('common_codes')->updateOrInsert(
|
||||||
|
[
|
||||||
|
'code_group' => $item['code_group'],
|
||||||
|
'code' => $item['code'],
|
||||||
|
'tenant_id' => $item['tenant_id'],
|
||||||
|
],
|
||||||
|
array_merge($item, [
|
||||||
|
'sort_order' => $index + 1,
|
||||||
|
'is_active' => true,
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->command->info('ItemTypeSeeder: '.count($itemTypes).'개 item_type 코드가 시딩되었습니다.');
|
||||||
|
}
|
||||||
|
}
|
||||||
1165
docs/specs/ITEM_MASTER_FIELD_INTEGRATION_PLAN.md
Normal file
1165
docs/specs/ITEM_MASTER_FIELD_INTEGRATION_PLAN.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user