2025-09-24 17:41:26 +09:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Services\Estimate;
|
|
|
|
|
|
|
|
|
|
|
|
use App\Models\Estimate\Estimate;
|
|
|
|
|
|
use App\Models\Estimate\EstimateItem;
|
2025-10-13 21:52:34 +09:00
|
|
|
|
use App\Services\Calculation\CalculationEngine;
|
2025-09-24 17:41:26 +09:00
|
|
|
|
use App\Services\ModelSet\ModelSetService;
|
2025-10-13 21:52:34 +09:00
|
|
|
|
use App\Services\Pricing\PricingService;
|
2025-09-24 17:41:26 +09:00
|
|
|
|
use App\Services\Service;
|
|
|
|
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
2025-10-13 21:52:34 +09:00
|
|
|
|
use Illuminate\Support\Facades\DB;
|
2025-09-24 17:41:26 +09:00
|
|
|
|
|
|
|
|
|
|
class EstimateService extends Service
|
|
|
|
|
|
{
|
|
|
|
|
|
protected ModelSetService $modelSetService;
|
2025-10-13 21:52:34 +09:00
|
|
|
|
|
2025-09-24 17:41:26 +09:00
|
|
|
|
protected CalculationEngine $calculationEngine;
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
protected PricingService $pricingService;
|
|
|
|
|
|
|
2025-09-24 17:41:26 +09:00
|
|
|
|
public function __construct(
|
|
|
|
|
|
ModelSetService $modelSetService,
|
2025-10-13 21:52:34 +09:00
|
|
|
|
CalculationEngine $calculationEngine,
|
|
|
|
|
|
PricingService $pricingService
|
2025-09-24 17:41:26 +09:00
|
|
|
|
) {
|
|
|
|
|
|
parent::__construct();
|
|
|
|
|
|
$this->modelSetService = $modelSetService;
|
|
|
|
|
|
$this->calculationEngine = $calculationEngine;
|
2025-10-13 21:52:34 +09:00
|
|
|
|
$this->pricingService = $pricingService;
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 목록 조회
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function getEstimates(array $filters = []): LengthAwarePaginator
|
|
|
|
|
|
{
|
|
|
|
|
|
$query = Estimate::with(['modelSet', 'items'])
|
|
|
|
|
|
->where('tenant_id', $this->tenantId());
|
|
|
|
|
|
|
|
|
|
|
|
// 필터링
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($filters['status'])) {
|
2025-09-24 17:41:26 +09:00
|
|
|
|
$query->where('status', $filters['status']);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($filters['customer_name'])) {
|
|
|
|
|
|
$query->where('customer_name', 'like', '%'.$filters['customer_name'].'%');
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($filters['model_set_id'])) {
|
2025-09-24 17:41:26 +09:00
|
|
|
|
$query->where('model_set_id', $filters['model_set_id']);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($filters['date_from'])) {
|
2025-09-24 17:41:26 +09:00
|
|
|
|
$query->whereDate('created_at', '>=', $filters['date_from']);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($filters['date_to'])) {
|
2025-09-24 17:41:26 +09:00
|
|
|
|
$query->whereDate('created_at', '<=', $filters['date_to']);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($filters['search'])) {
|
2025-09-24 17:41:26 +09:00
|
|
|
|
$searchTerm = $filters['search'];
|
|
|
|
|
|
$query->where(function ($q) use ($searchTerm) {
|
2025-10-13 21:52:34 +09:00
|
|
|
|
$q->where('estimate_name', 'like', '%'.$searchTerm.'%')
|
|
|
|
|
|
->orWhere('estimate_no', 'like', '%'.$searchTerm.'%')
|
|
|
|
|
|
->orWhere('project_name', 'like', '%'.$searchTerm.'%');
|
2025-09-24 17:41:26 +09:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $query->orderBy('created_at', 'desc')
|
2025-10-13 21:52:34 +09:00
|
|
|
|
->paginate($filters['per_page'] ?? 20);
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 상세 조회
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function getEstimateDetail($estimateId): array
|
|
|
|
|
|
{
|
|
|
|
|
|
$estimate = Estimate::with(['modelSet.fields', 'items'])
|
|
|
|
|
|
->where('tenant_id', $this->tenantId())
|
|
|
|
|
|
->findOrFail($estimateId);
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
'estimate' => $estimate,
|
|
|
|
|
|
'model_set_schema' => $this->modelSetService->getModelSetCategoryFields($estimate->model_set_id),
|
|
|
|
|
|
'calculation_summary' => $this->summarizeCalculations($estimate),
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 생성
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function createEstimate(array $data): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return DB::transaction(function () use ($data) {
|
|
|
|
|
|
// 견적번호 생성
|
|
|
|
|
|
$estimateNo = Estimate::generateEstimateNo($this->tenantId());
|
|
|
|
|
|
|
|
|
|
|
|
// 모델셋 기반 BOM 계산
|
|
|
|
|
|
$bomCalculation = $this->modelSetService->calculateModelSetBom(
|
|
|
|
|
|
$data['model_set_id'],
|
|
|
|
|
|
$data['parameters']
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// 견적 생성
|
|
|
|
|
|
$estimate = Estimate::create([
|
|
|
|
|
|
'tenant_id' => $this->tenantId(),
|
|
|
|
|
|
'model_set_id' => $data['model_set_id'],
|
|
|
|
|
|
'estimate_no' => $estimateNo,
|
|
|
|
|
|
'estimate_name' => $data['estimate_name'],
|
|
|
|
|
|
'customer_name' => $data['customer_name'] ?? null,
|
|
|
|
|
|
'project_name' => $data['project_name'] ?? null,
|
|
|
|
|
|
'parameters' => $data['parameters'],
|
|
|
|
|
|
'calculated_results' => $bomCalculation['calculated_values'] ?? [],
|
|
|
|
|
|
'bom_data' => $bomCalculation,
|
2025-10-13 21:52:34 +09:00
|
|
|
|
'total_amount' => 0, // 항목 생성 후 재계산
|
2025-09-24 17:41:26 +09:00
|
|
|
|
'notes' => $data['notes'] ?? null,
|
|
|
|
|
|
'valid_until' => now()->addDays(30), // 기본 30일 유효
|
|
|
|
|
|
'created_by' => $this->apiUserId(),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
// 견적 항목 생성 (BOM 기반) + 가격 계산
|
|
|
|
|
|
if (! empty($bomCalculation['bom_items'])) {
|
|
|
|
|
|
$totalAmount = $this->createEstimateItems(
|
|
|
|
|
|
$estimate,
|
|
|
|
|
|
$bomCalculation['bom_items'],
|
|
|
|
|
|
$data['client_id'] ?? null
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// 총액 업데이트
|
|
|
|
|
|
$estimate->update(['total_amount' => $totalAmount]);
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $this->getEstimateDetail($estimate->id);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 수정
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function updateEstimate($estimateId, array $data): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return DB::transaction(function () use ($estimateId, $data) {
|
|
|
|
|
|
$estimate = Estimate::where('tenant_id', $this->tenantId())
|
|
|
|
|
|
->findOrFail($estimateId);
|
|
|
|
|
|
|
|
|
|
|
|
// 파라미터가 변경되면 재계산
|
|
|
|
|
|
if (isset($data['parameters'])) {
|
|
|
|
|
|
$bomCalculation = $this->modelSetService->calculateModelSetBom(
|
|
|
|
|
|
$estimate->model_set_id,
|
|
|
|
|
|
$data['parameters']
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
$data['calculated_results'] = $bomCalculation['calculated_values'] ?? [];
|
|
|
|
|
|
$data['bom_data'] = $bomCalculation;
|
|
|
|
|
|
|
|
|
|
|
|
// 기존 견적 항목 삭제 후 재생성
|
|
|
|
|
|
$estimate->items()->delete();
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($bomCalculation['bom_items'])) {
|
|
|
|
|
|
$totalAmount = $this->createEstimateItems(
|
|
|
|
|
|
$estimate,
|
|
|
|
|
|
$bomCalculation['bom_items'],
|
|
|
|
|
|
$data['client_id'] ?? null
|
|
|
|
|
|
);
|
|
|
|
|
|
$data['total_amount'] = $totalAmount;
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$estimate->update([
|
|
|
|
|
|
...$data,
|
|
|
|
|
|
'updated_by' => $this->apiUserId(),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
return $this->getEstimateDetail($estimate->id);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 삭제
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function deleteEstimate($estimateId): void
|
|
|
|
|
|
{
|
|
|
|
|
|
DB::transaction(function () use ($estimateId) {
|
|
|
|
|
|
$estimate = Estimate::where('tenant_id', $this->tenantId())
|
|
|
|
|
|
->findOrFail($estimateId);
|
|
|
|
|
|
|
|
|
|
|
|
// 진행 중인 견적은 삭제 불가
|
|
|
|
|
|
if (in_array($estimate->status, ['SENT', 'APPROVED'])) {
|
|
|
|
|
|
throw new \Exception(__('error.estimate.cannot_delete_sent_or_approved'));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$estimate->update(['deleted_by' => $this->apiUserId()]);
|
|
|
|
|
|
$estimate->delete();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 복제
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function cloneEstimate($estimateId, array $data): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return DB::transaction(function () use ($estimateId, $data) {
|
|
|
|
|
|
$originalEstimate = Estimate::with('items')
|
|
|
|
|
|
->where('tenant_id', $this->tenantId())
|
|
|
|
|
|
->findOrFail($estimateId);
|
|
|
|
|
|
|
|
|
|
|
|
// 새 견적번호 생성
|
|
|
|
|
|
$newEstimateNo = Estimate::generateEstimateNo($this->tenantId());
|
|
|
|
|
|
|
|
|
|
|
|
// 견적 복제
|
|
|
|
|
|
$newEstimate = Estimate::create([
|
|
|
|
|
|
'tenant_id' => $this->tenantId(),
|
|
|
|
|
|
'model_set_id' => $originalEstimate->model_set_id,
|
|
|
|
|
|
'estimate_no' => $newEstimateNo,
|
|
|
|
|
|
'estimate_name' => $data['estimate_name'],
|
|
|
|
|
|
'customer_name' => $data['customer_name'] ?? $originalEstimate->customer_name,
|
|
|
|
|
|
'project_name' => $data['project_name'] ?? $originalEstimate->project_name,
|
|
|
|
|
|
'parameters' => $originalEstimate->parameters,
|
|
|
|
|
|
'calculated_results' => $originalEstimate->calculated_results,
|
|
|
|
|
|
'bom_data' => $originalEstimate->bom_data,
|
|
|
|
|
|
'total_amount' => $originalEstimate->total_amount,
|
|
|
|
|
|
'notes' => $data['notes'] ?? $originalEstimate->notes,
|
|
|
|
|
|
'valid_until' => now()->addDays(30),
|
|
|
|
|
|
'created_by' => $this->apiUserId(),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
// 견적 항목 복제
|
|
|
|
|
|
foreach ($originalEstimate->items as $item) {
|
|
|
|
|
|
EstimateItem::create([
|
|
|
|
|
|
'tenant_id' => $this->tenantId(),
|
|
|
|
|
|
'estimate_id' => $newEstimate->id,
|
|
|
|
|
|
'sequence' => $item->sequence,
|
|
|
|
|
|
'item_name' => $item->item_name,
|
|
|
|
|
|
'item_description' => $item->item_description,
|
|
|
|
|
|
'parameters' => $item->parameters,
|
|
|
|
|
|
'calculated_values' => $item->calculated_values,
|
|
|
|
|
|
'unit_price' => $item->unit_price,
|
|
|
|
|
|
'quantity' => $item->quantity,
|
|
|
|
|
|
'total_price' => $item->total_price,
|
|
|
|
|
|
'bom_components' => $item->bom_components,
|
|
|
|
|
|
'notes' => $item->notes,
|
|
|
|
|
|
'created_by' => $this->apiUserId(),
|
|
|
|
|
|
]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $this->getEstimateDetail($newEstimate->id);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 상태 변경
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function changeEstimateStatus($estimateId, string $status, ?string $notes = null): array
|
|
|
|
|
|
{
|
|
|
|
|
|
$estimate = Estimate::where('tenant_id', $this->tenantId())
|
|
|
|
|
|
->findOrFail($estimateId);
|
|
|
|
|
|
|
|
|
|
|
|
$validTransitions = [
|
|
|
|
|
|
'DRAFT' => ['SENT', 'REJECTED'],
|
|
|
|
|
|
'SENT' => ['APPROVED', 'REJECTED', 'EXPIRED'],
|
|
|
|
|
|
'APPROVED' => ['EXPIRED'],
|
|
|
|
|
|
'REJECTED' => ['DRAFT'],
|
|
|
|
|
|
'EXPIRED' => ['DRAFT'],
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! in_array($status, $validTransitions[$estimate->status] ?? [])) {
|
2025-09-24 17:41:26 +09:00
|
|
|
|
throw new \Exception(__('error.estimate.invalid_status_transition'));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$estimate->update([
|
|
|
|
|
|
'status' => $status,
|
2025-10-13 21:52:34 +09:00
|
|
|
|
'notes' => $notes ? ($estimate->notes."\n\n".$notes) : $estimate->notes,
|
2025-09-24 17:41:26 +09:00
|
|
|
|
'updated_by' => $this->apiUserId(),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
return $this->getEstimateDetail($estimate->id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 동적 견적 폼 스키마 조회
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function getEstimateFormSchema($modelSetId): array
|
|
|
|
|
|
{
|
|
|
|
|
|
$parameters = $this->modelSetService->getEstimateParameters($modelSetId);
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
'model_set' => $parameters['category'],
|
|
|
|
|
|
'form_schema' => [
|
|
|
|
|
|
'input_fields' => $parameters['input_fields'],
|
|
|
|
|
|
'calculated_fields' => $parameters['calculated_fields'],
|
|
|
|
|
|
],
|
|
|
|
|
|
'calculation_schema' => $parameters['calculation_schema'],
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 견적 파라미터 미리보기 계산
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function previewCalculation($modelSetId, array $parameters): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return $this->modelSetService->calculateModelSetBom($modelSetId, $parameters);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-10-13 21:52:34 +09:00
|
|
|
|
* 견적 항목 생성 (가격 계산 포함)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return float 총 견적 금액
|
2025-09-24 17:41:26 +09:00
|
|
|
|
*/
|
2025-10-13 21:52:34 +09:00
|
|
|
|
protected function createEstimateItems(Estimate $estimate, array $bomItems, ?int $clientId = null): float
|
2025-09-24 17:41:26 +09:00
|
|
|
|
{
|
2025-10-13 21:52:34 +09:00
|
|
|
|
$totalAmount = 0;
|
|
|
|
|
|
$warnings = [];
|
|
|
|
|
|
|
2025-09-24 17:41:26 +09:00
|
|
|
|
foreach ($bomItems as $index => $bomItem) {
|
2025-10-13 21:52:34 +09:00
|
|
|
|
$quantity = $bomItem['quantity'] ?? 1;
|
|
|
|
|
|
$unitPrice = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 가격 조회 (item_id와 item_type이 있는 경우)
|
|
|
|
|
|
if (isset($bomItem['item_id']) && isset($bomItem['item_type'])) {
|
|
|
|
|
|
$priceResult = $this->pricingService->getItemPrice(
|
|
|
|
|
|
$bomItem['item_type'], // 'PRODUCT' or 'MATERIAL'
|
|
|
|
|
|
$bomItem['item_id'],
|
|
|
|
|
|
$clientId,
|
|
|
|
|
|
now()->format('Y-m-d')
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
$unitPrice = $priceResult['price'] ?? 0;
|
|
|
|
|
|
|
|
|
|
|
|
if ($priceResult['warning']) {
|
|
|
|
|
|
$warnings[] = $priceResult['warning'];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$totalPrice = $unitPrice * $quantity;
|
|
|
|
|
|
$totalAmount += $totalPrice;
|
|
|
|
|
|
|
2025-09-24 17:41:26 +09:00
|
|
|
|
EstimateItem::create([
|
|
|
|
|
|
'tenant_id' => $this->tenantId(),
|
|
|
|
|
|
'estimate_id' => $estimate->id,
|
|
|
|
|
|
'sequence' => $index + 1,
|
2025-10-13 21:52:34 +09:00
|
|
|
|
'item_name' => $bomItem['name'] ?? '견적 항목 '.($index + 1),
|
2025-09-24 17:41:26 +09:00
|
|
|
|
'item_description' => $bomItem['description'] ?? '',
|
|
|
|
|
|
'parameters' => $bomItem['parameters'] ?? [],
|
|
|
|
|
|
'calculated_values' => $bomItem['calculated_values'] ?? [],
|
2025-10-13 21:52:34 +09:00
|
|
|
|
'unit_price' => $unitPrice,
|
|
|
|
|
|
'quantity' => $quantity,
|
|
|
|
|
|
'total_price' => $totalPrice,
|
2025-09-24 17:41:26 +09:00
|
|
|
|
'bom_components' => $bomItem['components'] ?? [],
|
|
|
|
|
|
'created_by' => $this->apiUserId(),
|
|
|
|
|
|
]);
|
|
|
|
|
|
}
|
2025-10-13 21:52:34 +09:00
|
|
|
|
|
|
|
|
|
|
// 가격 경고가 있으면 로그 기록
|
|
|
|
|
|
if (! empty($warnings)) {
|
|
|
|
|
|
\Log::warning('견적 가격 조회 경고', [
|
|
|
|
|
|
'estimate_id' => $estimate->id,
|
|
|
|
|
|
'warnings' => $warnings,
|
|
|
|
|
|
]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $totalAmount;
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 계산 결과 요약
|
|
|
|
|
|
*/
|
|
|
|
|
|
protected function summarizeCalculations(Estimate $estimate): array
|
|
|
|
|
|
{
|
|
|
|
|
|
$summary = [
|
|
|
|
|
|
'total_items' => $estimate->items->count(),
|
|
|
|
|
|
'total_amount' => $estimate->total_amount,
|
|
|
|
|
|
'key_calculations' => [],
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 주요 계산 결과 추출
|
2025-10-13 21:52:34 +09:00
|
|
|
|
if (! empty($estimate->calculated_results)) {
|
2025-09-24 17:41:26 +09:00
|
|
|
|
$results = $estimate->calculated_results;
|
|
|
|
|
|
|
|
|
|
|
|
if (isset($results['W1'], $results['H1'])) {
|
2025-10-13 21:52:34 +09:00
|
|
|
|
$summary['key_calculations']['제작사이즈'] = $results['W1'].' × '.$results['H1'].' mm';
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isset($results['weight'])) {
|
2025-10-13 21:52:34 +09:00
|
|
|
|
$summary['key_calculations']['중량'] = $results['weight'].' kg';
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isset($results['area'])) {
|
2025-10-13 21:52:34 +09:00
|
|
|
|
$summary['key_calculations']['면적'] = $results['area'].' ㎡';
|
2025-09-24 17:41:26 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isset($results['bracket_size'])) {
|
|
|
|
|
|
$summary['key_calculations']['모터브라켓'] = $results['bracket_size'];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $summary;
|
|
|
|
|
|
}
|
2025-10-13 21:52:34 +09:00
|
|
|
|
}
|