2025-12-30 23:45:22 +09:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
|
|
|
|
|
|
use App\Models\Tenants\Tenant;
|
2026-01-29 15:33:54 +09:00
|
|
|
|
use App\Traits\Auditable;
|
2025-12-30 23:45:22 +09:00
|
|
|
|
use App\Traits\BelongsToTenant;
|
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 카테고리 그룹 모델
|
|
|
|
|
|
*
|
|
|
|
|
|
* 품목 카테고리별 단가 계산 방식(면적/중량/수량 기반) 분류
|
|
|
|
|
|
* MNG 시뮬레이터와 동기화를 위한 핵심 테이블
|
|
|
|
|
|
*/
|
|
|
|
|
|
class CategoryGroup extends Model
|
|
|
|
|
|
{
|
2026-01-29 15:33:54 +09:00
|
|
|
|
use Auditable, BelongsToTenant;
|
2025-12-30 23:45:22 +09:00
|
|
|
|
|
|
|
|
|
|
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 int $tenantId 테넌트 ID
|
|
|
|
|
|
* @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,
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|