- products 테이블에 options JSON 컬럼 추가 (마이그레이션)
- Material/Product 모델에 options 필드 추가 (fillable, casts)
- SystemFields::PRODUCTS에 options 상수 추가
- MaterialService/ProductService에 동적 필드 자동 추출 로직:
- getKnownFields(): SystemFields + ItemField 기반 고정 필드 조회
- extractDynamicOptions(): 동적 필드 추출
- normalizeOptions(): [{label, value, unit}] 형태로 정규화
- material_code 중복 체크 시 soft delete 포함 (withTrashed)
- 사용 중인 자재 삭제 방지 (checkMaterialUsage)
- Material 모델에 category 관계 추가
146 lines
3.6 KiB
PHP
146 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Constants;
|
|
|
|
/**
|
|
* 테이블별 시스템 필드(고정 컬럼) 예약어 관리
|
|
*
|
|
* field_key 중복 검증 시 해당 테이블의 고정 컬럼과 충돌을 방지합니다.
|
|
* source_table (products, materials) 기반으로 대상 테이블을 결정합니다.
|
|
*/
|
|
class SystemFields
|
|
{
|
|
/**
|
|
* 소스 테이블 상수
|
|
*/
|
|
public const SOURCE_TABLE_PRODUCTS = 'products';
|
|
|
|
public const SOURCE_TABLE_MATERIALS = 'materials';
|
|
|
|
/**
|
|
* 그룹 ID 상수
|
|
*/
|
|
public const GROUP_ITEM_MASTER = 1; // 품목관리
|
|
|
|
/**
|
|
* products 테이블 고정 컬럼
|
|
*/
|
|
public const PRODUCTS = [
|
|
// 기본 정보
|
|
'code',
|
|
'name',
|
|
'unit',
|
|
'category_id',
|
|
'product_type',
|
|
'description',
|
|
// 플래그
|
|
'is_sellable',
|
|
'is_purchasable',
|
|
'is_producible',
|
|
'is_variable_size',
|
|
'is_active',
|
|
// 하이브리드 고정 필드
|
|
'safety_stock',
|
|
'lead_time',
|
|
'product_category',
|
|
'part_type',
|
|
// 파일 관련
|
|
'bending_diagram',
|
|
'bending_details',
|
|
'specification_file',
|
|
'specification_file_name',
|
|
'certification_file',
|
|
'certification_file_name',
|
|
'certification_number',
|
|
'certification_start_date',
|
|
'certification_end_date',
|
|
// JSON 필드
|
|
'attributes',
|
|
'attributes_archive',
|
|
'options',
|
|
];
|
|
|
|
/**
|
|
* materials 테이블 고정 컬럼
|
|
*/
|
|
public const MATERIALS = [
|
|
// 기본 정보
|
|
'name',
|
|
'item_name',
|
|
'specification',
|
|
'material_code',
|
|
'material_type',
|
|
'unit',
|
|
'category_id',
|
|
// 플래그
|
|
'is_inspection',
|
|
'is_active',
|
|
// 기타
|
|
'search_tag',
|
|
'remarks',
|
|
// JSON 필드
|
|
'attributes',
|
|
'options',
|
|
];
|
|
|
|
/**
|
|
* 공통 시스템 컬럼 (모든 테이블에 적용)
|
|
*/
|
|
public const COMMON = [
|
|
'id',
|
|
'tenant_id',
|
|
'created_by',
|
|
'updated_by',
|
|
'deleted_by',
|
|
'created_at',
|
|
'updated_at',
|
|
'deleted_at',
|
|
];
|
|
|
|
/**
|
|
* source_table 기반 예약어 목록 조회
|
|
*/
|
|
public static function getReservedKeys(string $sourceTable): array
|
|
{
|
|
$tableFields = match ($sourceTable) {
|
|
self::SOURCE_TABLE_PRODUCTS => self::PRODUCTS,
|
|
self::SOURCE_TABLE_MATERIALS => self::MATERIALS,
|
|
default => []
|
|
};
|
|
|
|
// 공통 시스템 컬럼 병합
|
|
return array_unique(array_merge(self::COMMON, $tableFields));
|
|
}
|
|
|
|
/**
|
|
* 특정 field_key가 시스템 필드인지 확인
|
|
*/
|
|
public static function isReserved(string $fieldKey, string $sourceTable): bool
|
|
{
|
|
return in_array($fieldKey, self::getReservedKeys($sourceTable), true);
|
|
}
|
|
|
|
/**
|
|
* group_id에 속한 모든 테이블의 예약어 목록 조회
|
|
* (item_type을 모를 때 안전하게 모든 예약어 체크)
|
|
*/
|
|
public static function getAllReservedKeysForGroup(int $groupId): array
|
|
{
|
|
$allFields = self::COMMON;
|
|
|
|
if ($groupId === self::GROUP_ITEM_MASTER) {
|
|
$allFields = array_merge($allFields, self::PRODUCTS, self::MATERIALS);
|
|
}
|
|
|
|
return array_unique($allFields);
|
|
}
|
|
|
|
/**
|
|
* 특정 field_key가 그룹 내 어떤 테이블에서든 시스템 필드인지 확인
|
|
*/
|
|
public static function isReservedInGroup(string $fieldKey, int $groupId): bool
|
|
{
|
|
return in_array($fieldKey, self::getAllReservedKeysForGroup($groupId), true);
|
|
}
|
|
}
|