- KdPriceTable 모델: 경동기업 단가 테이블 (motor, shaft, pipe, angle, raw_material, bdmodels) - KyungdongFormulaHandler: 모터 용량, 브라켓 크기, 절곡품(10종), 부자재(3종) 계산 - FormulaEvaluatorService: tenant_id=287 라우팅 추가 - kd_price_tables 마이그레이션 및 시더 (47건 단가 데이터) 테스트 결과: W0=3000, H0=2500 입력 시 16개 항목, 합계 751,200원 정상 계산 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
342 lines
9.1 KiB
PHP
342 lines
9.1 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Kyungdong;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
/**
|
|
* 경동기업 전용 단가 테이블 모델
|
|
*
|
|
* 5130 레거시 price_* 테이블 데이터 조회용
|
|
*
|
|
* @property int $id
|
|
* @property int $tenant_id
|
|
* @property string $table_type
|
|
* @property string|null $item_code
|
|
* @property string|null $item_name
|
|
* @property string|null $category
|
|
* @property string|null $spec1
|
|
* @property string|null $spec2
|
|
* @property string|null $spec3
|
|
* @property float $unit_price
|
|
* @property string $unit
|
|
* @property array|null $raw_data
|
|
* @property bool $is_active
|
|
*/
|
|
class KdPriceTable extends Model
|
|
{
|
|
// 테이블 유형 상수
|
|
public const TYPE_MOTOR = 'motor';
|
|
|
|
public const TYPE_SHAFT = 'shaft';
|
|
|
|
public const TYPE_PIPE = 'pipe';
|
|
|
|
public const TYPE_ANGLE = 'angle';
|
|
|
|
public const TYPE_RAW_MATERIAL = 'raw_material';
|
|
|
|
public const TYPE_BDMODELS = 'bdmodels';
|
|
|
|
// 경동기업 테넌트 ID
|
|
public const TENANT_ID = 287;
|
|
|
|
protected $table = 'kd_price_tables';
|
|
|
|
protected $fillable = [
|
|
'tenant_id',
|
|
'table_type',
|
|
'item_code',
|
|
'item_name',
|
|
'category',
|
|
'spec1',
|
|
'spec2',
|
|
'spec3',
|
|
'unit_price',
|
|
'unit',
|
|
'raw_data',
|
|
'is_active',
|
|
];
|
|
|
|
protected $casts = [
|
|
'unit_price' => 'decimal:2',
|
|
'raw_data' => 'array',
|
|
'is_active' => 'boolean',
|
|
];
|
|
|
|
// =========================================================================
|
|
// Scopes
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 테이블 유형으로 필터링
|
|
*/
|
|
public function scopeOfType(Builder $query, string $type): Builder
|
|
{
|
|
return $query->where('table_type', $type);
|
|
}
|
|
|
|
/**
|
|
* 활성 데이터만
|
|
*/
|
|
public function scopeActive(Builder $query): Builder
|
|
{
|
|
return $query->where('is_active', true);
|
|
}
|
|
|
|
/**
|
|
* 모터 단가 조회
|
|
*/
|
|
public function scopeMotor(Builder $query): Builder
|
|
{
|
|
return $query->ofType(self::TYPE_MOTOR)->active();
|
|
}
|
|
|
|
/**
|
|
* 샤프트 단가 조회
|
|
*/
|
|
public function scopeShaft(Builder $query): Builder
|
|
{
|
|
return $query->ofType(self::TYPE_SHAFT)->active();
|
|
}
|
|
|
|
/**
|
|
* 파이프 단가 조회
|
|
*/
|
|
public function scopePipeType(Builder $query): Builder
|
|
{
|
|
return $query->ofType(self::TYPE_PIPE)->active();
|
|
}
|
|
|
|
/**
|
|
* 앵글 단가 조회
|
|
*/
|
|
public function scopeAngle(Builder $query): Builder
|
|
{
|
|
return $query->ofType(self::TYPE_ANGLE)->active();
|
|
}
|
|
|
|
// =========================================================================
|
|
// Static Query Methods
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 모터 단가 조회
|
|
*
|
|
* @param string $motorCapacity 모터 용량 (150K, 300K, 400K, 500K, 600K, 800K, 1000K)
|
|
*/
|
|
public static function getMotorPrice(string $motorCapacity): float
|
|
{
|
|
$record = self::motor()
|
|
->where('category', $motorCapacity)
|
|
->first();
|
|
|
|
return (float) ($record?->unit_price ?? 0);
|
|
}
|
|
|
|
/**
|
|
* 제어기 단가 조회
|
|
*
|
|
* @param string $controllerType 제어기 타입 (매립형, 노출형, 뒷박스)
|
|
*/
|
|
public static function getControllerPrice(string $controllerType): float
|
|
{
|
|
$record = self::motor()
|
|
->where('category', $controllerType)
|
|
->first();
|
|
|
|
return (float) ($record?->unit_price ?? 0);
|
|
}
|
|
|
|
/**
|
|
* 샤프트 단가 조회
|
|
*
|
|
* @param string $size 사이즈 (3, 4, 5인치)
|
|
* @param float $length 길이 (m 단위)
|
|
*/
|
|
public static function getShaftPrice(string $size, float $length): float
|
|
{
|
|
// 길이를 소수점 1자리 문자열로 변환 (DB 저장 형식: '3.0', '4.0')
|
|
$lengthStr = number_format($length, 1, '.', '');
|
|
|
|
$record = self::shaft()
|
|
->where('spec1', $size)
|
|
->where('spec2', $lengthStr)
|
|
->first();
|
|
|
|
return (float) ($record?->unit_price ?? 0);
|
|
}
|
|
|
|
/**
|
|
* 파이프 단가 조회
|
|
*
|
|
* @param string $thickness 두께 (1.4 등)
|
|
* @param int $length 길이 (3000, 6000)
|
|
*/
|
|
public static function getPipePrice(string $thickness, int $length): float
|
|
{
|
|
$record = self::pipeType()
|
|
->where('spec1', $thickness)
|
|
->where('spec2', (string) $length)
|
|
->first();
|
|
|
|
return (float) ($record?->unit_price ?? 0);
|
|
}
|
|
|
|
/**
|
|
* 앵글 단가 조회
|
|
*
|
|
* @param string $type 타입 (스크린용, 철재용)
|
|
* @param string $bracketSize 브라켓크기 (530*320, 600*350, 690*390)
|
|
* @param string $angleType 앵글타입 (앵글3T, 앵글4T)
|
|
*/
|
|
public static function getAnglePrice(string $type, string $bracketSize, string $angleType): float
|
|
{
|
|
$record = self::angle()
|
|
->where('category', $type)
|
|
->where('spec1', $bracketSize)
|
|
->where('spec2', $angleType)
|
|
->first();
|
|
|
|
return (float) ($record?->unit_price ?? 0);
|
|
}
|
|
|
|
/**
|
|
* 원자재 단가 조회
|
|
*
|
|
* @param string $materialName 원자재명 (실리카, 스크린 등)
|
|
*/
|
|
public static function getRawMaterialPrice(string $materialName): float
|
|
{
|
|
$record = self::ofType(self::TYPE_RAW_MATERIAL)
|
|
->active()
|
|
->where('item_name', $materialName)
|
|
->first();
|
|
|
|
return (float) ($record?->unit_price ?? 0);
|
|
}
|
|
|
|
// =========================================================================
|
|
// BDmodels 단가 조회 (절곡품)
|
|
// =========================================================================
|
|
|
|
/**
|
|
* BDmodels 스코프
|
|
*/
|
|
public function scopeBdmodels(Builder $query): Builder
|
|
{
|
|
return $query->ofType(self::TYPE_BDMODELS)->active();
|
|
}
|
|
|
|
/**
|
|
* BDmodels 단가 조회 (케이스, 가이드레일, 하단마감재 등)
|
|
*
|
|
* @param string $secondItem 부품분류 (케이스, 가이드레일, 하단마감재, L-BAR 등)
|
|
* @param string|null $modelName 모델코드 (KSS01, KWS01 등)
|
|
* @param string|null $finishingType 마감재질 (SUS, EGI)
|
|
* @param string|null $spec 규격 (120*70, 650*550 등)
|
|
*/
|
|
public static function getBDModelPrice(
|
|
string $secondItem,
|
|
?string $modelName = null,
|
|
?string $finishingType = null,
|
|
?string $spec = null
|
|
): float {
|
|
$query = self::bdmodels()->where('category', $secondItem);
|
|
|
|
if ($modelName) {
|
|
$query->where('item_code', $modelName);
|
|
}
|
|
|
|
if ($finishingType) {
|
|
$query->where('spec1', $finishingType);
|
|
}
|
|
|
|
if ($spec) {
|
|
$query->where('spec2', $spec);
|
|
}
|
|
|
|
$record = $query->first();
|
|
|
|
return (float) ($record?->unit_price ?? 0);
|
|
}
|
|
|
|
/**
|
|
* 케이스 단가 조회
|
|
*
|
|
* @param string $spec 케이스 규격 (500*380, 650*550 등)
|
|
*/
|
|
public static function getCasePrice(string $spec): float
|
|
{
|
|
return self::getBDModelPrice('케이스', null, null, $spec);
|
|
}
|
|
|
|
/**
|
|
* 가이드레일 단가 조회
|
|
*
|
|
* @param string $modelName 모델코드 (KSS01 등)
|
|
* @param string $finishingType 마감재질 (SUS, EGI)
|
|
* @param string $spec 규격 (120*70, 120*100)
|
|
*/
|
|
public static function getGuideRailPrice(string $modelName, string $finishingType, string $spec): float
|
|
{
|
|
return self::getBDModelPrice('가이드레일', $modelName, $finishingType, $spec);
|
|
}
|
|
|
|
/**
|
|
* 하단마감재(하장바) 단가 조회
|
|
*
|
|
* @param string $modelName 모델코드
|
|
* @param string $finishingType 마감재질
|
|
*/
|
|
public static function getBottomBarPrice(string $modelName, string $finishingType): float
|
|
{
|
|
return self::getBDModelPrice('하단마감재', $modelName, $finishingType);
|
|
}
|
|
|
|
/**
|
|
* L-BAR 단가 조회
|
|
*
|
|
* @param string $modelName 모델코드
|
|
*/
|
|
public static function getLBarPrice(string $modelName): float
|
|
{
|
|
return self::getBDModelPrice('L-BAR', $modelName);
|
|
}
|
|
|
|
/**
|
|
* 보강평철 단가 조회
|
|
*/
|
|
public static function getFlatBarPrice(): float
|
|
{
|
|
return self::getBDModelPrice('보강평철');
|
|
}
|
|
|
|
/**
|
|
* 케이스 마구리 단가 조회
|
|
*
|
|
* @param string $spec 규격
|
|
*/
|
|
public static function getCaseCapPrice(string $spec): float
|
|
{
|
|
return self::getBDModelPrice('마구리', null, null, $spec);
|
|
}
|
|
|
|
/**
|
|
* 케이스용 연기차단재 단가 조회
|
|
*/
|
|
public static function getCaseSmokeBlockPrice(): float
|
|
{
|
|
return self::getBDModelPrice('케이스용 연기차단재');
|
|
}
|
|
|
|
/**
|
|
* 가이드레일용 연기차단재 단가 조회
|
|
*/
|
|
public static function getRailSmokeBlockPrice(): float
|
|
{
|
|
return self::getBDModelPrice('가이드레일용 연기차단재');
|
|
}
|
|
}
|