166 lines
4.8 KiB
PHP
166 lines
4.8 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Helpers;
|
||
|
|
|
||
|
|
use App\Models\Products\CommonCode;
|
||
|
|
use Illuminate\Support\Facades\Cache;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 품목 유형(item_type) 관련 헬퍼 클래스
|
||
|
|
*
|
||
|
|
* - 품목 유형 코드(FG/PT/SM/RM/CS) → 테이블(products/materials) 매핑
|
||
|
|
* - 테넌트별 캐시 적용
|
||
|
|
*/
|
||
|
|
class ItemTypeHelper
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 캐시 TTL (초)
|
||
|
|
*/
|
||
|
|
private const CACHE_TTL = 3600; // 1시간
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 캐시 키 프리픽스
|
||
|
|
*/
|
||
|
|
private const CACHE_PREFIX = 'item_types:tenant:';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 테넌트별 품목 유형 목록 조회 (캐시 적용)
|
||
|
|
*
|
||
|
|
* @return array<string, array{code: string, name: string, source_table: string}>
|
||
|
|
*/
|
||
|
|
public static function getTypesByTenant(int $tenantId): array
|
||
|
|
{
|
||
|
|
$cacheKey = self::CACHE_PREFIX.$tenantId;
|
||
|
|
|
||
|
|
return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($tenantId) {
|
||
|
|
$codes = CommonCode::query()
|
||
|
|
->where(function ($query) use ($tenantId) {
|
||
|
|
$query->where('tenant_id', $tenantId)
|
||
|
|
->orWhereNull('tenant_id');
|
||
|
|
})
|
||
|
|
->where('code_group', 'item_type')
|
||
|
|
->where('is_active', true)
|
||
|
|
->orderBy('sort_order')
|
||
|
|
->get(['code', 'name', 'attributes']);
|
||
|
|
|
||
|
|
$result = [];
|
||
|
|
foreach ($codes as $code) {
|
||
|
|
$attributes = is_array($code->attributes) ? $code->attributes : json_decode($code->attributes, true) ?? [];
|
||
|
|
$result[$code->code] = [
|
||
|
|
'code' => $code->code,
|
||
|
|
'name' => $code->name,
|
||
|
|
'source_table' => $attributes['source_table'] ?? 'products',
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 품목 유형이 Material인지 확인
|
||
|
|
*
|
||
|
|
* @param string $itemType 품목 유형 코드 (FG/PT/SM/RM/CS)
|
||
|
|
* @param int $tenantId 테넌트 ID
|
||
|
|
*/
|
||
|
|
public static function isMaterial(string $itemType, int $tenantId): bool
|
||
|
|
{
|
||
|
|
return self::getSourceTable($itemType, $tenantId) === 'materials';
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 품목 유형이 Product인지 확인
|
||
|
|
*
|
||
|
|
* @param string $itemType 품목 유형 코드 (FG/PT/SM/RM/CS)
|
||
|
|
* @param int $tenantId 테넌트 ID
|
||
|
|
*/
|
||
|
|
public static function isProduct(string $itemType, int $tenantId): bool
|
||
|
|
{
|
||
|
|
return self::getSourceTable($itemType, $tenantId) === 'products';
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 품목 유형에 해당하는 소스 테이블 반환
|
||
|
|
*
|
||
|
|
* @param string $itemType 품목 유형 코드 (FG/PT/SM/RM/CS)
|
||
|
|
* @param int $tenantId 테넌트 ID
|
||
|
|
* @return string 'products' | 'materials'
|
||
|
|
*/
|
||
|
|
public static function getSourceTable(string $itemType, int $tenantId): string
|
||
|
|
{
|
||
|
|
$itemType = strtoupper($itemType);
|
||
|
|
$types = self::getTypesByTenant($tenantId);
|
||
|
|
|
||
|
|
if (isset($types[$itemType])) {
|
||
|
|
return $types[$itemType]['source_table'];
|
||
|
|
}
|
||
|
|
|
||
|
|
// 기본 매핑 (캐시 미스 또는 알 수 없는 타입)
|
||
|
|
return self::getDefaultSourceTable($itemType);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 기본 소스 테이블 매핑 (DB 조회 없이)
|
||
|
|
*
|
||
|
|
* @param string $itemType 품목 유형 코드
|
||
|
|
* @return string 'products' | 'materials'
|
||
|
|
*/
|
||
|
|
public static function getDefaultSourceTable(string $itemType): string
|
||
|
|
{
|
||
|
|
$itemType = strtoupper($itemType);
|
||
|
|
|
||
|
|
// Material 타입: SM, RM, CS
|
||
|
|
if (in_array($itemType, ['SM', 'RM', 'CS'])) {
|
||
|
|
return 'materials';
|
||
|
|
}
|
||
|
|
|
||
|
|
// Product 타입: FG, PT (기본값)
|
||
|
|
return 'products';
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 캐시 무효화
|
||
|
|
*/
|
||
|
|
public static function clearCache(int $tenantId): void
|
||
|
|
{
|
||
|
|
$cacheKey = self::CACHE_PREFIX.$tenantId;
|
||
|
|
Cache::forget($cacheKey);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 전체 캐시 무효화 (모든 테넌트)
|
||
|
|
*/
|
||
|
|
public static function clearAllCache(): void
|
||
|
|
{
|
||
|
|
// 패턴 기반 삭제는 캐시 드라이버에 따라 지원 여부가 다름
|
||
|
|
// 간단히 태그 기반 캐시나 개별 삭제를 권장
|
||
|
|
// 여기서는 특정 테넌트 캐시만 삭제하는 것을 권장
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 유효한 품목 유형인지 확인
|
||
|
|
*
|
||
|
|
* @param string $itemType 품목 유형 코드
|
||
|
|
* @param int $tenantId 테넌트 ID
|
||
|
|
*/
|
||
|
|
public static function isValidType(string $itemType, int $tenantId): bool
|
||
|
|
{
|
||
|
|
$itemType = strtoupper($itemType);
|
||
|
|
$types = self::getTypesByTenant($tenantId);
|
||
|
|
|
||
|
|
return isset($types[$itemType]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 모든 유효한 품목 유형 코드 목록 반환
|
||
|
|
*
|
||
|
|
* @return array<string>
|
||
|
|
*/
|
||
|
|
public static function getValidTypeCodes(int $tenantId): array
|
||
|
|
{
|
||
|
|
$types = self::getTypesByTenant($tenantId);
|
||
|
|
|
||
|
|
return array_keys($types);
|
||
|
|
}
|
||
|
|
}
|