Files
sam-manage/resources/views/rd/ai-quotation/document.blade.php
김보곤 25795f8612 feat: [ai-quotation] 제조 견적서 자동 생성 기능 추가
- AI 2단계 분석: 고객 인터뷰 → 요구사항 추출 → 견적 산출
- 모델 확장: AiQuotation(모드/견적번호), AiQuotationItem(규격/단가/금액)
- AiQuotePriceTable 모델 신규 생성
- Create 페이지: 모듈/제조 모드 탭, 제품 카테고리, 고객 정보 입력
- Show 페이지: 제조 모드 분기 렌더링 (품목/금액/고객정보)
- Edit 페이지: 품목 인라인 편집, 할인/부가세/조건 입력
- Document: 한국 표준 제조업 견적서 양식 템플릿
- Controller/Route: update 엔드포인트, edit 라우트 추가
2026-03-03 15:58:16 +09:00

145 lines
5.8 KiB
PHP

@extends('layouts.document')
@section('title', '견적서')
@push('styles')
<style>
/* 템플릿 선택 UI */
.template-selector { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; padding: 16px 0; }
.template-card {
width: 120px; text-decoration: none; color: inherit; border: 2px solid #e5e7eb;
border-radius: 10px; overflow: hidden; transition: all 0.2s; cursor: pointer;
}
.template-card:hover { border-color: #3b82f6; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
.template-card.active { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,0.2); }
.template-card .preview {
height: 64px; display: flex; align-items: center; justify-content: center;
font-size: 10px; font-weight: 600; letter-spacing: 0.2em;
}
.template-card .label { padding: 6px 0; text-align: center; font-size: 11px; font-weight: 500; background: #f9fafb; }
.template-card.active .label { background: #eff6ff; color: #1d4ed8; }
/* 미리보기 색상 */
.preview-classic { background: #fff; border-bottom: 2px solid #1f2937; color: #1f2937; }
.preview-modern { background: #f9fafb; border-bottom: 2px solid #9ca3af; color: #6b7280; }
.preview-blue { background: linear-gradient(135deg, #1e40af, #3b82f6); color: #fff; }
.preview-dark { background: #111827; color: #fbbf24; }
.preview-colorful { background: linear-gradient(135deg, #f59e0b, #ef4444); color: #fff; }
</style>
@endpush
@section('content')
@php
// 한글 금액 변환 함수
if (!function_exists('numberToKorean')) {
function numberToKorean(int $number): string {
return \App\Services\Rd\AiQuotationService::numberToKorean($number);
}
}
// 견적 모드 판별
$isManufacture = $quotation->isManufacture();
// 템플릿 (기본값: classic)
$template = $template ?? 'classic';
if ($isManufacture) {
// 제조 견적서 데이터
$options = $quotation->options ?? [];
$client = $options['client'] ?? [];
$project = $options['project'] ?? [];
$pricing = $options['pricing'] ?? [];
$terms = $options['terms'] ?? [];
$quotationNo = $quotation->quote_number ?? 'AQ-'.$quotation->created_at->format('Y').'-'.str_pad($quotation->id, 3, '0', STR_PAD_LEFT);
$subtotal = (int) ($pricing['subtotal'] ?? 0);
$discountRate = (float) ($pricing['discount_rate'] ?? 0);
$discountAmount = (int) ($pricing['discount_amount'] ?? 0);
$vatAmount = (int) ($pricing['vat_amount'] ?? 0);
$finalAmount = (int) ($pricing['final_amount'] ?? 0);
$subtotalKorean = numberToKorean($subtotal);
$validUntil = $terms['valid_until'] ?? now()->addDays(30)->format('Y-m-d');
$templates = [
'classic' => '클래식',
];
} else {
// 모듈 추천 견적서 데이터 (기존)
$quotationNo = 'AQ-' . $quotation->created_at->format('Y') . '-' . str_pad($quotation->id, 3, '0', STR_PAD_LEFT);
$company = $quotation->analysis_result['company_analysis'] ?? [];
$plan = $quotation->quotation_result['implementation_plan'] ?? [];
$estimatedMonths = $plan['estimated_months'] ?? null;
$devSubtotal = (int) $quotation->total_dev_cost;
$monthlySubtotal = (int) $quotation->total_monthly_fee;
$devVat = (int) round($devSubtotal * 0.1);
$monthlyVat = (int) round($monthlySubtotal * 0.1);
$devTotal = $devSubtotal + $devVat;
$monthlyTotal = $monthlySubtotal + $monthlyVat;
$devTotalKorean = numberToKorean($devSubtotal);
$sortedItems = $quotation->items->sortByDesc('is_required')->values();
$templates = [
'classic' => '클래식',
'modern' => '모던',
'blue' => '블루',
'dark' => '다크',
'colorful' => '컬러풀',
];
}
@endphp
{{-- 템플릿 선택 UI (인쇄 숨김) --}}
<div class="no-print" style="max-width: 700px; margin: 24px auto 0;">
<div class="template-selector">
@foreach($templates as $key => $label)
<a href="?template={{ $key }}"
class="template-card {{ $template === $key ? 'active' : '' }}">
<div class="preview preview-{{ $key }}"> </div>
<div class="label">{{ $label }}</div>
</a>
@endforeach
</div>
{{-- PDF 다운로드 버튼 --}}
<div class="text-center mt-3">
<button onclick="window.print()" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition text-sm">
<i class="ri-printer-line"></i> 인쇄 / PDF 다운로드
</button>
</div>
</div>
{{-- 선택된 템플릿 렌더링 --}}
@if($isManufacture)
@include('rd.ai-quotation.document-templates.manufacture-classic', [
'quotation' => $quotation,
'quotationNo' => $quotationNo,
'client' => $client,
'project' => $project,
'pricing' => $pricing,
'terms' => $terms,
'subtotal' => $subtotal,
'discountRate' => $discountRate,
'discountAmount' => $discountAmount,
'vatAmount' => $vatAmount,
'finalAmount' => $finalAmount,
'subtotalKorean' => $subtotalKorean,
'validUntil' => $validUntil,
])
@else
@include('rd.ai-quotation.document-templates.' . $template, [
'quotation' => $quotation,
'quotationNo' => $quotationNo,
'company' => $company,
'estimatedMonths' => $estimatedMonths,
'devSubtotal' => $devSubtotal,
'monthlySubtotal' => $monthlySubtotal,
'devVat' => $devVat,
'monthlyVat' => $monthlyVat,
'devTotal' => $devTotal,
'monthlyTotal' => $monthlyTotal,
'devTotalKorean' => $devTotalKorean,
'sortedItems' => $sortedItems,
])
@endif
@endsection