feat: 견적 시뮬레이터 개선 및 FlowTester 조건 평가기 추가

- 견적 시뮬레이터 UI 레이아웃 개선 (가로 배치, 반응형)
- FlowTester ConditionEvaluator 클래스 추가 (조건부 실행 지원)
- FormulaEvaluatorService 기능 확장
- DependencyResolver 의존성 해결 로직 개선
- PushDeviceToken 모델 확장 (FCM 토큰 관리)
- QuoteFormula API 엔드포인트 추가
- FlowTester 가이드 모달 업데이트
This commit is contained in:
2025-12-23 23:41:37 +09:00
parent f5ec9d502c
commit 60618ddd04
14 changed files with 1892 additions and 349 deletions

View File

@@ -289,6 +289,11 @@ public function simulate(Request $request): JsonResponse
$validated['input_variables']
);
// 품목 상세 정보 및 BOM 트리 추가
if (! empty($result['items'])) {
$result['items'] = $this->evaluatorService->enrichItemsWithDetails($result['items']);
}
// 오류가 있어도 계산된 결과는 반환 (부분 성공)
// 오류는 data.errors에 포함되어 UI에서 별도 표시
return response()->json([
@@ -311,4 +316,69 @@ public function duplicate(int $id): JsonResponse
'data' => $formula,
]);
}
/**
* 전체 품목 목록 (시뮬레이터용)
*/
public function items(Request $request): JsonResponse
{
$tenantId = session('selected_tenant_id');
if (! $tenantId) {
return response()->json([
'success' => false,
'message' => '테넌트를 선택해주세요.',
], 400);
}
$query = \DB::table('items')
->where('tenant_id', $tenantId)
->whereNull('deleted_at')
->where('is_active', true);
// 검색
if ($search = $request->get('search')) {
$query->where(function ($q) use ($search) {
$q->where('code', 'like', "%{$search}%")
->orWhere('name', 'like', "%{$search}%");
});
}
// 품목 유형 필터
if ($itemType = $request->get('item_type')) {
$query->where('item_type', $itemType);
}
$items = $query->orderBy('item_type')
->orderBy('code')
->get(['id', 'code', 'name', 'item_type', 'unit', 'bom']);
// BOM 정보 가공
$items = $items->map(function ($item) {
$bomData = json_decode($item->bom ?? '[]', true);
return [
'id' => $item->id,
'code' => $item->code,
'name' => $item->name,
'item_type' => $item->item_type,
'item_type_label' => $this->evaluatorService->getItemTypeLabel($item->item_type),
'unit' => $item->unit,
'has_bom' => ! empty($bomData),
'bom_count' => count($bomData),
];
});
// 품목 유형별 통계
$stats = $items->groupBy('item_type')->map(fn ($group) => $group->count());
return response()->json([
'success' => true,
'data' => [
'items' => $items->values(),
'stats' => $stats,
'total' => $items->count(),
],
]);
}
}