Files
sam-manage/app/Models/CategoryGroup.php
hskwon b718234472 feat: 시뮬레이터 동기화를 위한 DB 스키마 확장
- items 테이블에 process_type, item_category 필드 추가
- category_groups 테이블 생성 (면적/중량/수량 기반 단가 계산 분류)
- CategoryGroup 모델 및 단가 계산 헬퍼 메서드 구현
2025-12-24 14:23:53 +09:00

133 lines
3.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Models;
use App\Models\Tenants\Tenant;
use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* 카테고리 그룹 모델
*
* 품목 카테고리별 단가 계산 방식(면적/중량/수량 기반) 분류
* Design 시뮬레이터와 동기화를 위한 핵심 테이블
*/
class CategoryGroup extends Model
{
use BelongsToTenant;
protected $table = 'category_groups';
protected $fillable = [
'tenant_id',
'code',
'name',
'multiplier_variable',
'categories',
'description',
'sort_order',
'is_active',
];
protected function casts(): array
{
return [
'categories' => 'array',
'sort_order' => 'integer',
'is_active' => 'boolean',
];
}
/**
* 단가 계산 방식 상수
*/
public const CODE_AREA_BASED = 'area_based'; // 면적 기반 (M)
public const CODE_WEIGHT_BASED = 'weight_based'; // 중량 기반 (K)
public const CODE_QUANTITY_BASED = 'quantity_based'; // 수량 기반 (null)
/**
* 곱셈 변수 상수
*/
public const MULTIPLIER_AREA = 'M'; // 면적 (㎡)
public const MULTIPLIER_WEIGHT = 'K'; // 중량 (kg)
/**
* 테넌트 관계
*/
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class);
}
/**
* 품목 카테고리로 해당 그룹 조회
*
* @param string $itemCategory 품목분류 (원단, 패널, 도장 등)
*/
public static function findByItemCategory(int $tenantId, string $itemCategory): ?self
{
return static::where('tenant_id', $tenantId)
->where('is_active', true)
->whereJsonContains('categories', $itemCategory)
->first();
}
/**
* 곱셈 변수 값 계산
*
* @param array $variables 계산 변수 배열 ['M' => 6.099, 'K' => 25.5, ...]
* @return float 곱셈 값 (없으면 1)
*/
public function getMultiplierValue(array $variables): float
{
if (empty($this->multiplier_variable)) {
return 1.0;
}
return (float) ($variables[$this->multiplier_variable] ?? 1.0);
}
/**
* 단가 계산
*
* @param float $basePrice 기본 단가
* @param array $variables 계산 변수 배열
* @return array ['final_price' => float, 'calculation_note' => string, 'multiplier' => float]
*/
public function calculatePrice(float $basePrice, array $variables): array
{
$multiplier = $this->getMultiplierValue($variables);
if ($multiplier === 1.0) {
return [
'final_price' => $basePrice,
'calculation_note' => '수량단가',
'multiplier' => 1.0,
];
}
$unit = match ($this->multiplier_variable) {
self::MULTIPLIER_AREA => '㎡',
self::MULTIPLIER_WEIGHT => 'kg',
default => '',
};
return [
'final_price' => $basePrice * $multiplier,
'calculation_note' => sprintf(
'%s (%s원/%s × %.3f%s)',
$this->name,
number_format($basePrice),
$unit,
$multiplier,
$unit
),
'multiplier' => $multiplier,
];
}
}