feat: [ai-quotation] 견적서 5종 템플릿 선택 시스템 추가
- classic(클래식), modern(모던), blue(블루), dark(다크), colorful(컬러풀) 5종 - 문서 상단 미리보기 카드 클릭으로 즉시 디자인 전환 - URL 쿼리 파라미터 ?template=xxx 방식, 기본값 classic - 인쇄/PDF 시 선택 UI 자동 숨김 (no-print) - 기존 디자인은 classic 템플릿으로 100% 보존
This commit is contained in:
@@ -57,7 +57,7 @@ public function createQuotation(Request $request): View|\Illuminate\Http\Respons
|
||||
/**
|
||||
* AI 견적 문서 (인쇄용 견적서)
|
||||
*/
|
||||
public function documentQuotation(int $id): View
|
||||
public function documentQuotation(Request $request, int $id): View
|
||||
{
|
||||
$quotation = $this->quotationService->getById($id);
|
||||
|
||||
@@ -65,7 +65,13 @@ public function documentQuotation(int $id): View
|
||||
abort(404, '완료된 견적만 문서로 조회할 수 있습니다.');
|
||||
}
|
||||
|
||||
return view('rd.ai-quotation.document', compact('quotation'));
|
||||
$template = $request->query('template', 'classic');
|
||||
$allowed = ['classic', 'modern', 'blue', 'dark', 'colorful'];
|
||||
if (! in_array($template, $allowed)) {
|
||||
$template = 'classic';
|
||||
}
|
||||
|
||||
return view('rd.ai-quotation.document', compact('quotation', 'template'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
{{-- 블루 프로페셔널 견적서 템플릿 --}}
|
||||
<style>
|
||||
.blue { font-family: 'Pretendard', sans-serif; color: #1e293b; }
|
||||
.blue .doc-table { width: 100%; border-collapse: collapse; }
|
||||
.blue .doc-table th, .blue .doc-table td { padding: 7px 10px; font-size: 13px; border: 1px solid #cbd5e1; }
|
||||
.blue .doc-table thead th { background: linear-gradient(135deg, #1e40af, #2563eb); color: #fff; border-color: #1e40af; font-weight: 600; }
|
||||
.blue .doc-table tbody tr:nth-child(even) { background-color: #f0f5ff; }
|
||||
.blue .doc-table tfoot td, .blue .doc-table tfoot th { border-color: #cbd5e1; }
|
||||
.blue .header-bar { background: linear-gradient(135deg, #1e40af, #3b82f6); color: #fff; padding: 20px 28px; border-radius: 0; margin: -18mm -22mm 24px; width: calc(100% + 44mm); }
|
||||
.blue .seal-box { display: inline-block; width: 60px; height: 60px; border: 2px solid #1e40af; border-radius: 50%; text-align: center; line-height: 56px; color: #1e40af; font-weight: 700; font-size: 16px; }
|
||||
|
||||
@media print {
|
||||
.blue .header-bar { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
.blue .doc-table thead th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="blue document-page max-w-[210mm] mx-auto my-8 bg-white shadow-lg" style="padding: 18mm 22mm;">
|
||||
|
||||
{{-- 블루 헤더 바 --}}
|
||||
<div class="header-bar" style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<div>
|
||||
<h1 style="font-size: 28px; font-weight: 700; letter-spacing: 0.4em; margin: 0;">견 적 서</h1>
|
||||
<p style="font-size: 11px; opacity: 0.8; margin-top: 4px;">QUOTATION</p>
|
||||
</div>
|
||||
<div style="text-align: right; font-size: 12px; opacity: 0.9;">
|
||||
<p>{{ $quotationNo }}</p>
|
||||
<p>{{ $quotation->created_at->format('Y. m. d') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 견적 정보 --}}
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 6px; font-size: 12px; color: #64748b;">
|
||||
<p>유효기간: 견적일로부터 30일</p>
|
||||
</div>
|
||||
|
||||
{{-- 수신 / 공급자 --}}
|
||||
<table class="doc-table mb-6">
|
||||
<colgroup>
|
||||
<col style="width: 8%;"><col style="width: 42%;"><col style="width: 8%;"><col style="width: 42%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2" class="text-center">수 신</th>
|
||||
<th colspan="2" class="text-center">공 급 자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="font-weight:600; background:#f8fafc;">귀사명</td><td>{{ $quotation->title }}</td>
|
||||
<td style="font-weight:600; background:#f8fafc;">상 호</td><td>(주)코드브릿지엑스</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight:600; background:#f8fafc;">업 종</td><td>{{ $company['industry'] ?? '-' }}</td>
|
||||
<td style="font-weight:600; background:#f8fafc;">대 표</td><td>이의찬</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight:600; background:#f8fafc;">규 모</td><td>{{ $company['scale'] ?? '-' }}</td>
|
||||
<td style="font-weight:600; background:#f8fafc;">주 소</td><td>인천 남동구 남동대로 215번길 30</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight:600; background:#f8fafc;">현재시스템</td><td>{{ !empty($company['current_systems']) ? implode(', ', $company['current_systems']) : '-' }}</td>
|
||||
<td style="font-weight:600; background:#f8fafc;">연락처</td><td>032-123-4567</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{-- 합계 --}}
|
||||
<div style="margin-bottom: 24px; padding: 16px 20px; border: 2px solid #2563eb; border-radius: 8px; text-align: center; background: linear-gradient(to right, #eff6ff, #ffffff);">
|
||||
<p style="font-size: 12px; color: #64748b; margin-bottom: 6px;">아래와 같이 견적합니다.</p>
|
||||
<p style="font-size: 20px; font-weight: 700; color: #1e40af;">
|
||||
합계금액: 금 {{ $devTotalKorean }}원정
|
||||
<span style="font-size: 14px; font-weight: 400; color: #475569;">(₩{{ number_format($devSubtotal) }})</span>
|
||||
</p>
|
||||
<p style="font-size: 11px; color: #94a3b8; margin-top: 4px;">※ 부가가치세 별도 / 월 구독료 {{ number_format($monthlySubtotal) }}원 별도</p>
|
||||
</div>
|
||||
|
||||
{{-- 품목 --}}
|
||||
<table class="doc-table" style="margin-bottom: 24px;">
|
||||
<colgroup>
|
||||
<col style="width: 5%;"><col style="width: 7%;"><col style="width: 20%;"><col style="width: 33%;"><col style="width: 17.5%;"><col style="width: 17.5%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">No</th><th class="text-center">구분</th><th class="text-center">품 목</th>
|
||||
<th class="text-center">설 명</th><th class="text-center">개발비 (원)</th><th class="text-center">월 구독료 (원)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($sortedItems as $index => $item)
|
||||
<tr>
|
||||
<td class="text-center">{{ $index + 1 }}</td>
|
||||
<td class="text-center">
|
||||
<span style="font-size: 11px; padding: 1px 6px; border-radius: 3px; {{ $item->is_required ? 'background:#dbeafe;color:#1e40af;' : 'background:#f1f5f9;color:#64748b;' }}">
|
||||
{{ $item->is_required ? '필수' : '선택' }}
|
||||
</span>
|
||||
</td>
|
||||
<td style="font-weight: 500;">{{ $item->module_name }}</td>
|
||||
<td style="font-size: 12px; color: #64748b;">{{ Str::limit($item->reason, 80) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->dev_cost) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->monthly_fee) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right">소 계</th>
|
||||
<td class="text-right font-bold">{{ number_format($devSubtotal) }}</td>
|
||||
<td class="text-right font-bold">{{ number_format($monthlySubtotal) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right">부가세 (10%)</th>
|
||||
<td class="text-right">{{ number_format($devVat) }}</td>
|
||||
<td class="text-right">{{ number_format($monthlyVat) }}</td>
|
||||
</tr>
|
||||
<tr style="background: linear-gradient(to right, #eff6ff, #dbeafe); -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<th colspan="4" class="text-right" style="font-size: 15px; color: #1e40af;">합 계</th>
|
||||
<td class="text-right font-bold" style="font-size: 15px; color: #1e40af;">{{ number_format($devTotal) }}</td>
|
||||
<td class="text-right font-bold" style="font-size: 15px; color: #1e40af;">{{ number_format($monthlyTotal) }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{-- 비고 --}}
|
||||
<div style="margin-bottom: 28px;">
|
||||
<table class="doc-table">
|
||||
<thead><tr><th class="text-left" style="font-size: 13px;">비 고</th></tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding: 12px 16px;">
|
||||
<ol style="list-style: decimal; padding-left: 18px; font-size: 12px; color: #475569; line-height: 1.8;">
|
||||
<li>상기 금액은 부가가치세 별도입니다.</li>
|
||||
<li>개발비 납부 조건: 계약 시 50%, 완료 시 50% 분할 납부</li>
|
||||
<li>월 구독료: 서비스 오픈일부터 과금 (월 {{ number_format($monthlyTotal) }}원, VAT 포함)</li>
|
||||
@if($estimatedMonths)
|
||||
<li>예상 구축 기간: {{ $estimatedMonths }}개월</li>
|
||||
@endif
|
||||
<li>본 견적서의 유효기간은 견적일로부터 30일입니다.</li>
|
||||
<li>세부 사항은 별도 협의를 통해 조정될 수 있습니다.</li>
|
||||
</ol>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- 서명 --}}
|
||||
<div class="flex justify-end items-center gap-6 mt-12">
|
||||
<div class="text-right">
|
||||
<p style="font-size: 16px; font-weight: 700; color: #1e40af;">(주)코드브릿지엑스</p>
|
||||
<p style="font-size: 12px; color: #64748b; margin-top: 4px;">대표이사 이 의 찬</p>
|
||||
</div>
|
||||
<div class="seal-box">(인)</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,142 @@
|
||||
{{-- 클래식 견적서 템플릿 — 전통 한국 제조업 스타일 --}}
|
||||
<style>
|
||||
.classic .doc-table { width: 100%; border-collapse: collapse; }
|
||||
.classic .doc-table th, .classic .doc-table td { border: 1px solid #333; padding: 6px 10px; font-size: 13px; }
|
||||
.classic .doc-table th { background-color: #f3f4f6; font-weight: 600; }
|
||||
.classic .seal-box { display: inline-block; width: 60px; height: 60px; border: 2px solid #dc2626; border-radius: 50%; text-align: center; line-height: 56px; color: #dc2626; font-weight: 700; font-size: 16px; }
|
||||
</style>
|
||||
|
||||
<div class="classic document-page max-w-[210mm] mx-auto my-8 bg-white shadow-lg" style="padding: 15mm 20mm;">
|
||||
|
||||
{{-- 제목 --}}
|
||||
<h1 class="text-center text-3xl font-bold tracking-[0.5em] mb-8 pb-4 border-b-2 border-gray-800">
|
||||
견 적 서
|
||||
</h1>
|
||||
|
||||
{{-- 견적 정보 --}}
|
||||
<div class="flex justify-between mb-6 text-sm">
|
||||
<div>
|
||||
<p><span class="font-semibold">견적번호:</span> {{ $quotationNo }}</p>
|
||||
<p><span class="font-semibold">유효기간:</span> 견적일로부터 30일</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p><span class="font-semibold">견적일자:</span> {{ $quotation->created_at->format('Y년 m월 d일') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 수신 / 공급자 --}}
|
||||
<table class="doc-table mb-6">
|
||||
<colgroup>
|
||||
<col style="width: 8%;"><col style="width: 42%;"><col style="width: 8%;"><col style="width: 42%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2" class="text-center" style="background-color: #eff6ff;">수 신</th>
|
||||
<th colspan="2" class="text-center" style="background-color: #f0fdf4;">공 급 자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>귀사명</th><td>{{ $quotation->title }}</td>
|
||||
<th>상 호</th><td>(주)코드브릿지엑스</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>업 종</th><td>{{ $company['industry'] ?? '-' }}</td>
|
||||
<th>대 표</th><td>이의찬</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>규 모</th><td>{{ $company['scale'] ?? '-' }}</td>
|
||||
<th>주 소</th><td>인천 남동구 남동대로 215번길 30</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>현재시스템</th><td>{{ !empty($company['current_systems']) ? implode(', ', $company['current_systems']) : '-' }}</td>
|
||||
<th>연락처</th><td>032-123-4567</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{-- 합계 --}}
|
||||
<div class="mb-6 p-4 border-2 border-gray-800 text-center">
|
||||
<p class="text-sm mb-2">아래와 같이 견적합니다.</p>
|
||||
<p class="text-xl font-bold">
|
||||
합계금액: 금 {{ $devTotalKorean }}원정
|
||||
<span class="text-base font-normal">(₩{{ number_format($devSubtotal) }})</span>
|
||||
</p>
|
||||
<p class="text-xs text-gray-600 mt-1">※ 부가가치세 별도 / 월 구독료 {{ number_format($monthlySubtotal) }}원 별도</p>
|
||||
</div>
|
||||
|
||||
{{-- 품목 --}}
|
||||
<table class="doc-table mb-6">
|
||||
<colgroup>
|
||||
<col style="width: 5%;"><col style="width: 7%;"><col style="width: 20%;"><col style="width: 33%;"><col style="width: 17.5%;"><col style="width: 17.5%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">No</th><th class="text-center">구분</th><th class="text-center">품 목</th>
|
||||
<th class="text-center">설 명</th><th class="text-center">개발비 (원)</th><th class="text-center">월 구독료 (원)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($sortedItems as $index => $item)
|
||||
<tr>
|
||||
<td class="text-center">{{ $index + 1 }}</td>
|
||||
<td class="text-center">{{ $item->is_required ? '필수' : '선택' }}</td>
|
||||
<td>{{ $item->module_name }}</td>
|
||||
<td class="text-xs">{{ Str::limit($item->reason, 80) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->dev_cost) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->monthly_fee) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right">소 계</th>
|
||||
<td class="text-right font-bold">{{ number_format($devSubtotal) }}</td>
|
||||
<td class="text-right font-bold">{{ number_format($monthlySubtotal) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right">부가세 (10%)</th>
|
||||
<td class="text-right">{{ number_format($devVat) }}</td>
|
||||
<td class="text-right">{{ number_format($monthlyVat) }}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #f3f4f6;">
|
||||
<th colspan="4" class="text-right text-base">합 계</th>
|
||||
<td class="text-right font-bold text-base">{{ number_format($devTotal) }}</td>
|
||||
<td class="text-right font-bold text-base">{{ number_format($monthlyTotal) }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{-- 비고 --}}
|
||||
<div class="mb-8">
|
||||
<table class="doc-table">
|
||||
<thead><tr><th class="text-left">비 고</th></tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-sm leading-relaxed" style="padding: 12px 16px;">
|
||||
<ol class="list-decimal list-inside space-y-1">
|
||||
<li>상기 금액은 부가가치세 별도입니다.</li>
|
||||
<li>개발비 납부 조건: 계약 시 50%, 완료 시 50% 분할 납부</li>
|
||||
<li>월 구독료: 서비스 오픈일부터 과금 (월 {{ number_format($monthlyTotal) }}원, VAT 포함)</li>
|
||||
@if($estimatedMonths)
|
||||
<li>예상 구축 기간: {{ $estimatedMonths }}개월</li>
|
||||
@endif
|
||||
<li>본 견적서의 유효기간은 견적일로부터 30일입니다.</li>
|
||||
<li>세부 사항은 별도 협의를 통해 조정될 수 있습니다.</li>
|
||||
</ol>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- 서명 --}}
|
||||
<div class="flex justify-end items-center gap-6 mt-12">
|
||||
<div class="text-right">
|
||||
<p class="text-lg font-bold mb-1">(주)코드브릿지엑스</p>
|
||||
<p class="text-sm text-gray-600">대표이사 이 의 찬</p>
|
||||
</div>
|
||||
<div class="seal-box">(인)</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,133 @@
|
||||
{{-- 컬러풀/캐주얼 견적서 템플릿 --}}
|
||||
<style>
|
||||
.colorful { font-family: 'Pretendard', sans-serif; color: #1f2937; }
|
||||
.colorful .doc-table { width: 100%; border-collapse: separate; border-spacing: 0; border-radius: 12px; overflow: hidden; border: 1px solid #e5e7eb; }
|
||||
.colorful .doc-table th, .colorful .doc-table td { padding: 8px 12px; font-size: 13px; border-bottom: 1px solid #f3e8ff; }
|
||||
.colorful .doc-table thead th { background: linear-gradient(135deg, #7c3aed, #a855f7); color: #fff; font-weight: 600; border-bottom: none; }
|
||||
.colorful .doc-table tbody tr:nth-child(even) { background-color: #faf5ff; }
|
||||
.colorful .doc-table tbody tr:hover { background-color: #f3e8ff; }
|
||||
.colorful .doc-table tfoot td, .colorful .doc-table tfoot th { border-bottom: none; }
|
||||
.colorful .seal-box { display: inline-block; width: 60px; height: 60px; border: 2px solid #a855f7; border-radius: 50%; text-align: center; line-height: 56px; color: #a855f7; font-weight: 700; font-size: 16px; }
|
||||
.colorful .card { border-radius: 12px; overflow: hidden; }
|
||||
|
||||
@media print {
|
||||
.colorful .doc-table thead th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
.colorful .doc-table tbody tr:nth-child(even) { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="colorful document-page max-w-[210mm] mx-auto my-8 bg-white shadow-lg" style="padding: 18mm 22mm;">
|
||||
|
||||
{{-- 그라데이션 헤더 --}}
|
||||
<div class="card" style="background: linear-gradient(135deg, #f59e0b, #ef4444); padding: 24px 28px; margin-bottom: 28px; -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<div>
|
||||
<h1 style="font-size: 28px; font-weight: 700; letter-spacing: 0.4em; color: #fff; margin: 0;">견 적 서</h1>
|
||||
<p style="font-size: 11px; color: rgba(255,255,255,0.8); margin-top: 4px;">QUOTATION</p>
|
||||
</div>
|
||||
<div style="text-align: right; color: rgba(255,255,255,0.9); font-size: 12px;">
|
||||
<p style="font-weight: 600;">{{ $quotationNo }}</p>
|
||||
<p>{{ $quotation->created_at->format('Y. m. d') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 수신 / 공급자 카드 --}}
|
||||
<div style="display: flex; gap: 16px; margin-bottom: 24px;">
|
||||
<div class="card" style="flex: 1; padding: 16px 20px; background: linear-gradient(135deg, #fef3c7, #fde68a); -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<p style="font-size: 11px; color: #92400e; font-weight: 700; margin-bottom: 8px;">수 신</p>
|
||||
<p style="font-size: 15px; font-weight: 700; color: #78350f; margin-bottom: 4px;">{{ $quotation->title }}</p>
|
||||
<p style="font-size: 12px; color: #92400e;">{{ $company['industry'] ?? '-' }} · {{ $company['scale'] ?? '-' }}</p>
|
||||
@if(!empty($company['current_systems']))
|
||||
<p style="font-size: 11px; color: #a16207; margin-top: 4px;">현재: {{ implode(', ', $company['current_systems']) }}</p>
|
||||
@endif
|
||||
</div>
|
||||
<div class="card" style="flex: 1; padding: 16px 20px; background: linear-gradient(135deg, #ede9fe, #ddd6fe); -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<p style="font-size: 11px; color: #5b21b6; font-weight: 700; margin-bottom: 8px;">공 급 자</p>
|
||||
<p style="font-size: 15px; font-weight: 700; color: #4c1d95; margin-bottom: 4px;">(주)코드브릿지엑스</p>
|
||||
<p style="font-size: 12px; color: #6d28d9;">대표 이의찬</p>
|
||||
<p style="font-size: 11px; color: #7c3aed; margin-top: 4px;">인천 남동구 남동대로 215번길 30 · 032-123-4567</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 합계 카드 --}}
|
||||
<div class="card" style="margin-bottom: 24px; padding: 20px; background: linear-gradient(135deg, #fef3c7, #fff7ed); border: 2px solid #f59e0b; text-align: center; -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<p style="font-size: 12px; color: #92400e; margin-bottom: 8px;">아래와 같이 견적합니다.</p>
|
||||
<p style="font-size: 22px; font-weight: 700; color: #b45309;">
|
||||
합계금액: 금 {{ $devTotalKorean }}원정
|
||||
<span style="font-size: 14px; font-weight: 400; color: #78350f;">(₩{{ number_format($devSubtotal) }})</span>
|
||||
</p>
|
||||
<p style="font-size: 11px; color: #a16207; margin-top: 6px;">※ 부가가치세 별도 / 월 구독료 {{ number_format($monthlySubtotal) }}원 별도</p>
|
||||
</div>
|
||||
|
||||
{{-- 품목 --}}
|
||||
<table class="doc-table" style="margin-bottom: 24px;">
|
||||
<colgroup>
|
||||
<col style="width: 5%;"><col style="width: 7%;"><col style="width: 20%;"><col style="width: 33%;"><col style="width: 17.5%;"><col style="width: 17.5%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">No</th><th class="text-center">구분</th><th class="text-center">품 목</th>
|
||||
<th class="text-center">설 명</th><th class="text-center">개발비 (원)</th><th class="text-center">월 구독료 (원)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($sortedItems as $index => $item)
|
||||
<tr>
|
||||
<td class="text-center" style="color: #9ca3af;">{{ $index + 1 }}</td>
|
||||
<td class="text-center">
|
||||
<span style="font-size: 11px; padding: 2px 8px; border-radius: 10px; font-weight: 600; {{ $item->is_required ? 'background:linear-gradient(135deg,#fbbf24,#f59e0b);color:#78350f;' : 'background:#f3f4f6;color:#6b7280;' }} -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
{{ $item->is_required ? '필수' : '선택' }}
|
||||
</span>
|
||||
</td>
|
||||
<td style="font-weight: 600;">{{ $item->module_name }}</td>
|
||||
<td style="font-size: 12px; color: #6b7280;">{{ Str::limit($item->reason, 80) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->dev_cost) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->monthly_fee) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr style="background: #faf5ff; -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<th colspan="4" class="text-right" style="color: #7c3aed;">소 계</th>
|
||||
<td class="text-right" style="font-weight: 700; color: #7c3aed;">{{ number_format($devSubtotal) }}</td>
|
||||
<td class="text-right" style="font-weight: 700; color: #7c3aed;">{{ number_format($monthlySubtotal) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right" style="color: #9ca3af;">부가세 (10%)</th>
|
||||
<td class="text-right" style="color: #9ca3af;">{{ number_format($devVat) }}</td>
|
||||
<td class="text-right" style="color: #9ca3af;">{{ number_format($monthlyVat) }}</td>
|
||||
</tr>
|
||||
<tr style="background: linear-gradient(135deg, #ede9fe, #ddd6fe); -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<th colspan="4" class="text-right" style="font-size: 15px; color: #5b21b6;">합 계</th>
|
||||
<td class="text-right" style="font-size: 15px; font-weight: 700; color: #5b21b6;">{{ number_format($devTotal) }}</td>
|
||||
<td class="text-right" style="font-size: 15px; font-weight: 700; color: #5b21b6;">{{ number_format($monthlyTotal) }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{-- 비고 --}}
|
||||
<div class="card" style="margin-bottom: 28px; padding: 16px 20px; background: #faf5ff; border: 1px solid #e9d5ff; -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<p style="font-size: 11px; color: #7c3aed; font-weight: 700; margin-bottom: 8px;">비 고</p>
|
||||
<ol style="list-style: decimal; padding-left: 18px; font-size: 12px; color: #6b7280; line-height: 1.8;">
|
||||
<li>상기 금액은 부가가치세 별도입니다.</li>
|
||||
<li>개발비 납부 조건: 계약 시 50%, 완료 시 50% 분할 납부</li>
|
||||
<li>월 구독료: 서비스 오픈일부터 과금 (월 {{ number_format($monthlyTotal) }}원, VAT 포함)</li>
|
||||
@if($estimatedMonths)
|
||||
<li>예상 구축 기간: {{ $estimatedMonths }}개월</li>
|
||||
@endif
|
||||
<li>본 견적서의 유효기간은 견적일로부터 30일입니다.</li>
|
||||
<li>세부 사항은 별도 협의를 통해 조정될 수 있습니다.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{{-- 서명 --}}
|
||||
<div style="display: flex; justify-content: flex-end; align-items: center; gap: 24px; margin-top: 48px;">
|
||||
<div style="text-align: right;">
|
||||
<p style="font-size: 16px; font-weight: 700; color: #5b21b6;">(주)코드브릿지엑스</p>
|
||||
<p style="font-size: 12px; color: #7c3aed; margin-top: 4px;">대표이사 이 의 찬</p>
|
||||
</div>
|
||||
<div class="seal-box">(인)</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,147 @@
|
||||
{{-- 프리미엄 다크 견적서 템플릿 --}}
|
||||
<style>
|
||||
.dark-tpl { font-family: 'Pretendard', sans-serif; color: #e5e7eb; background: #111827 !important; }
|
||||
.dark-tpl .doc-table { width: 100%; border-collapse: collapse; }
|
||||
.dark-tpl .doc-table th, .dark-tpl .doc-table td { padding: 7px 10px; font-size: 13px; border: 1px solid #374151; }
|
||||
.dark-tpl .doc-table thead th { background: #1f2937; color: #fbbf24; font-weight: 600; border-color: #374151; }
|
||||
.dark-tpl .doc-table tbody tr:nth-child(even) { background-color: #1a2332; }
|
||||
.dark-tpl .doc-table tbody td { color: #d1d5db; }
|
||||
.dark-tpl .doc-table tbody th { color: #9ca3af; background: #1f2937; }
|
||||
.dark-tpl .seal-box { display: inline-block; width: 60px; height: 60px; border: 2px solid #fbbf24; border-radius: 50%; text-align: center; line-height: 56px; color: #fbbf24; font-weight: 700; font-size: 16px; }
|
||||
|
||||
@media print {
|
||||
.dark-tpl { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
.dark-tpl .doc-table thead th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
.dark-tpl .doc-table tbody tr:nth-child(even) { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="dark-tpl document-page max-w-[210mm] mx-auto my-8 shadow-lg" style="padding: 18mm 22mm; background: #111827;">
|
||||
|
||||
{{-- 골드 라인 + 제목 --}}
|
||||
<div style="border-top: 3px solid #fbbf24; padding-top: 20px; margin-bottom: 32px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
|
||||
<div>
|
||||
<h1 style="font-size: 30px; font-weight: 300; letter-spacing: 0.6em; color: #fbbf24; margin: 0;">견 적 서</h1>
|
||||
<p style="font-size: 11px; color: #6b7280; margin-top: 4px; letter-spacing: 0.2em;">PREMIUM QUOTATION</p>
|
||||
</div>
|
||||
<div style="text-align: right; font-size: 12px; color: #6b7280;">
|
||||
<p>No. {{ $quotationNo }}</p>
|
||||
<p>{{ $quotation->created_at->format('Y. m. d') }}</p>
|
||||
<p style="margin-top: 2px;">유효기간: 견적일로부터 30일</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 수신 / 공급자 --}}
|
||||
<table class="doc-table mb-6">
|
||||
<colgroup>
|
||||
<col style="width: 8%;"><col style="width: 42%;"><col style="width: 8%;"><col style="width: 42%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2" class="text-center">수 신</th>
|
||||
<th colspan="2" class="text-center">공 급 자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>귀사명</th><td style="color: #f9fafb; font-weight: 500;">{{ $quotation->title }}</td>
|
||||
<th>상 호</th><td style="color: #f9fafb; font-weight: 500;">(주)코드브릿지엑스</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>업 종</th><td>{{ $company['industry'] ?? '-' }}</td>
|
||||
<th>대 표</th><td>이의찬</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>규 모</th><td>{{ $company['scale'] ?? '-' }}</td>
|
||||
<th>주 소</th><td>인천 남동구 남동대로 215번길 30</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>현재시스템</th><td>{{ !empty($company['current_systems']) ? implode(', ', $company['current_systems']) : '-' }}</td>
|
||||
<th>연락처</th><td>032-123-4567</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{-- 합계 --}}
|
||||
<div style="margin-bottom: 24px; padding: 18px 20px; border: 1px solid #fbbf24; text-align: center; background: linear-gradient(135deg, #1f2937, #111827);">
|
||||
<p style="font-size: 12px; color: #6b7280; margin-bottom: 8px;">아래와 같이 견적합니다.</p>
|
||||
<p style="font-size: 22px; font-weight: 300; color: #fbbf24;">
|
||||
합계금액: 금 <strong>{{ $devTotalKorean }}</strong>원정
|
||||
<span style="font-size: 14px; color: #9ca3af;">(₩{{ number_format($devSubtotal) }})</span>
|
||||
</p>
|
||||
<p style="font-size: 11px; color: #6b7280; margin-top: 6px;">※ 부가가치세 별도 / 월 구독료 {{ number_format($monthlySubtotal) }}원 별도</p>
|
||||
</div>
|
||||
|
||||
{{-- 품목 --}}
|
||||
<table class="doc-table" style="margin-bottom: 24px;">
|
||||
<colgroup>
|
||||
<col style="width: 5%;"><col style="width: 7%;"><col style="width: 20%;"><col style="width: 33%;"><col style="width: 17.5%;"><col style="width: 17.5%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">No</th><th class="text-center">구분</th><th class="text-center">품 목</th>
|
||||
<th class="text-center">설 명</th><th class="text-center">개발비 (원)</th><th class="text-center">월 구독료 (원)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($sortedItems as $index => $item)
|
||||
<tr>
|
||||
<td class="text-center" style="color: #6b7280;">{{ $index + 1 }}</td>
|
||||
<td class="text-center">
|
||||
<span style="font-size: 11px; padding: 1px 6px; border-radius: 3px; {{ $item->is_required ? 'background:#422006;color:#fbbf24;' : 'background:#1f2937;color:#6b7280;' }}">
|
||||
{{ $item->is_required ? '필수' : '선택' }}
|
||||
</span>
|
||||
</td>
|
||||
<td style="font-weight: 500; color: #f3f4f6;">{{ $item->module_name }}</td>
|
||||
<td style="font-size: 12px; color: #9ca3af;">{{ Str::limit($item->reason, 80) }}</td>
|
||||
<td class="text-right" style="color: #d1d5db;">{{ number_format((int) $item->dev_cost) }}</td>
|
||||
<td class="text-right" style="color: #d1d5db;">{{ number_format((int) $item->monthly_fee) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right" style="color: #9ca3af;">소 계</th>
|
||||
<td class="text-right" style="font-weight: 700; color: #e5e7eb;">{{ number_format($devSubtotal) }}</td>
|
||||
<td class="text-right" style="font-weight: 700; color: #e5e7eb;">{{ number_format($monthlySubtotal) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right" style="color: #6b7280;">부가세 (10%)</th>
|
||||
<td class="text-right" style="color: #6b7280;">{{ number_format($devVat) }}</td>
|
||||
<td class="text-right" style="color: #6b7280;">{{ number_format($monthlyVat) }}</td>
|
||||
</tr>
|
||||
<tr style="background: #1f2937; -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<th colspan="4" class="text-right" style="font-size: 15px; color: #fbbf24; border-color: #374151;">합 계</th>
|
||||
<td class="text-right" style="font-size: 15px; font-weight: 700; color: #fbbf24; border-color: #374151;">{{ number_format($devTotal) }}</td>
|
||||
<td class="text-right" style="font-size: 15px; font-weight: 700; color: #fbbf24; border-color: #374151;">{{ number_format($monthlyTotal) }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{-- 비고 --}}
|
||||
<div style="margin-bottom: 28px; padding: 16px 20px; border: 1px solid #374151; background: #1f2937; -webkit-print-color-adjust: exact; print-color-adjust: exact;">
|
||||
<p style="font-size: 11px; color: #fbbf24; font-weight: 600; margin-bottom: 8px; letter-spacing: 0.15em;">비 고</p>
|
||||
<ol style="list-style: decimal; padding-left: 18px; font-size: 12px; color: #9ca3af; line-height: 1.8;">
|
||||
<li>상기 금액은 부가가치세 별도입니다.</li>
|
||||
<li>개발비 납부 조건: 계약 시 50%, 완료 시 50% 분할 납부</li>
|
||||
<li>월 구독료: 서비스 오픈일부터 과금 (월 {{ number_format($monthlyTotal) }}원, VAT 포함)</li>
|
||||
@if($estimatedMonths)
|
||||
<li>예상 구축 기간: {{ $estimatedMonths }}개월</li>
|
||||
@endif
|
||||
<li>본 견적서의 유효기간은 견적일로부터 30일입니다.</li>
|
||||
<li>세부 사항은 별도 협의를 통해 조정될 수 있습니다.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{{-- 서명 --}}
|
||||
<div style="display: flex; justify-content: flex-end; align-items: center; gap: 24px; margin-top: 48px; padding-top: 20px; border-top: 1px solid #374151;">
|
||||
<div style="text-align: right;">
|
||||
<p style="font-size: 16px; font-weight: 600; color: #f9fafb;">(주)코드브릿지엑스</p>
|
||||
<p style="font-size: 12px; color: #6b7280; margin-top: 4px;">대표이사 이 의 찬</p>
|
||||
</div>
|
||||
<div class="seal-box">(인)</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,124 @@
|
||||
{{-- 모던/미니멀 견적서 템플릿 --}}
|
||||
<style>
|
||||
.modern { font-family: 'Pretendard', sans-serif; color: #374151; }
|
||||
.modern .doc-table { width: 100%; border-collapse: collapse; }
|
||||
.modern .doc-table th, .modern .doc-table td { padding: 8px 12px; font-size: 13px; border-bottom: 1px solid #e5e7eb; }
|
||||
.modern .doc-table th { font-weight: 500; color: #6b7280; background: transparent; }
|
||||
.modern .doc-table thead th { border-bottom: 2px solid #d1d5db; color: #374151; font-weight: 600; }
|
||||
.modern .doc-table tbody tr:nth-child(even) { background-color: #f9fafb; }
|
||||
.modern .doc-table tfoot td, .modern .doc-table tfoot th { border-top: 2px solid #d1d5db; border-bottom: none; }
|
||||
.modern .seal-line { width: 120px; border-bottom: 1px solid #9ca3af; display: inline-block; margin-left: 8px; }
|
||||
</style>
|
||||
|
||||
<div class="modern document-page max-w-[210mm] mx-auto my-8 bg-white shadow-lg" style="padding: 18mm 22mm;">
|
||||
|
||||
{{-- 헤더 --}}
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 32px; padding-bottom: 16px; border-bottom: 1px solid #e5e7eb;">
|
||||
<div>
|
||||
<h1 style="font-size: 28px; font-weight: 300; letter-spacing: 0.3em; color: #111827; margin: 0;">견적서</h1>
|
||||
<p style="font-size: 12px; color: #9ca3af; margin-top: 4px;">QUOTATION</p>
|
||||
</div>
|
||||
<div style="text-align: right; font-size: 12px; color: #6b7280;">
|
||||
<p>No. {{ $quotationNo }}</p>
|
||||
<p>{{ $quotation->created_at->format('Y. m. d') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 수신 / 공급자 --}}
|
||||
<div style="display: flex; gap: 24px; margin-bottom: 28px;">
|
||||
<div style="flex: 1; padding: 16px; background: #f9fafb; border-radius: 8px;">
|
||||
<p style="font-size: 11px; color: #9ca3af; font-weight: 600; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.1em;">수신</p>
|
||||
<p style="font-size: 15px; font-weight: 600; margin-bottom: 4px;">{{ $quotation->title }}</p>
|
||||
<p style="font-size: 12px; color: #6b7280;">{{ $company['industry'] ?? '-' }} · {{ $company['scale'] ?? '-' }}</p>
|
||||
@if(!empty($company['current_systems']))
|
||||
<p style="font-size: 11px; color: #9ca3af; margin-top: 4px;">현재: {{ implode(', ', $company['current_systems']) }}</p>
|
||||
@endif
|
||||
</div>
|
||||
<div style="flex: 1; padding: 16px; background: #f9fafb; border-radius: 8px;">
|
||||
<p style="font-size: 11px; color: #9ca3af; font-weight: 600; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.1em;">공급자</p>
|
||||
<p style="font-size: 15px; font-weight: 600; margin-bottom: 4px;">(주)코드브릿지엑스</p>
|
||||
<p style="font-size: 12px; color: #6b7280;">대표 이의찬</p>
|
||||
<p style="font-size: 11px; color: #9ca3af; margin-top: 4px;">인천 남동구 남동대로 215번길 30 · 032-123-4567</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 합계 --}}
|
||||
<div style="margin-bottom: 28px; padding: 20px; border: 1px solid #e5e7eb; border-radius: 8px; text-align: center;">
|
||||
<p style="font-size: 12px; color: #9ca3af; margin-bottom: 8px;">아래와 같이 견적합니다.</p>
|
||||
<p style="font-size: 22px; font-weight: 300; color: #111827;">
|
||||
금 <strong>{{ $devTotalKorean }}</strong>원정
|
||||
<span style="font-size: 14px; color: #6b7280; font-weight: 400;">(₩{{ number_format($devSubtotal) }})</span>
|
||||
</p>
|
||||
<p style="font-size: 11px; color: #9ca3af; margin-top: 6px;">부가가치세 별도 · 월 구독료 {{ number_format($monthlySubtotal) }}원 별도</p>
|
||||
</div>
|
||||
|
||||
{{-- 품목 --}}
|
||||
<table class="doc-table" style="margin-bottom: 28px;">
|
||||
<colgroup>
|
||||
<col style="width: 5%;"><col style="width: 7%;"><col style="width: 20%;"><col style="width: 33%;"><col style="width: 17.5%;"><col style="width: 17.5%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">No</th><th class="text-center">구분</th><th>품목</th>
|
||||
<th>설명</th><th class="text-right">개발비</th><th class="text-right">월 구독료</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($sortedItems as $index => $item)
|
||||
<tr>
|
||||
<td class="text-center" style="color: #9ca3af;">{{ $index + 1 }}</td>
|
||||
<td class="text-center">
|
||||
<span style="font-size: 11px; padding: 2px 6px; border-radius: 4px; {{ $item->is_required ? 'background:#dbeafe;color:#1d4ed8;' : 'background:#f3f4f6;color:#6b7280;' }}">
|
||||
{{ $item->is_required ? '필수' : '선택' }}
|
||||
</span>
|
||||
</td>
|
||||
<td style="font-weight: 500;">{{ $item->module_name }}</td>
|
||||
<td style="font-size: 12px; color: #6b7280;">{{ Str::limit($item->reason, 80) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->dev_cost) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->monthly_fee) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right">소계</th>
|
||||
<td class="text-right font-bold">{{ number_format($devSubtotal) }}</td>
|
||||
<td class="text-right font-bold">{{ number_format($monthlySubtotal) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right" style="color: #9ca3af;">VAT (10%)</th>
|
||||
<td class="text-right" style="color: #9ca3af;">{{ number_format($devVat) }}</td>
|
||||
<td class="text-right" style="color: #9ca3af;">{{ number_format($monthlyVat) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right" style="font-size: 15px;">합계</th>
|
||||
<td class="text-right font-bold" style="font-size: 15px;">{{ number_format($devTotal) }}</td>
|
||||
<td class="text-right font-bold" style="font-size: 15px;">{{ number_format($monthlyTotal) }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{-- 비고 --}}
|
||||
<div style="margin-bottom: 32px; padding: 16px 20px; background: #f9fafb; border-radius: 8px;">
|
||||
<p style="font-size: 11px; color: #9ca3af; font-weight: 600; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.1em;">비고</p>
|
||||
<ol style="list-style: decimal; padding-left: 18px; font-size: 12px; color: #6b7280; line-height: 1.8;">
|
||||
<li>상기 금액은 부가가치세 별도입니다.</li>
|
||||
<li>개발비 납부 조건: 계약 시 50%, 완료 시 50% 분할 납부</li>
|
||||
<li>월 구독료: 서비스 오픈일부터 과금 (월 {{ number_format($monthlyTotal) }}원, VAT 포함)</li>
|
||||
@if($estimatedMonths)
|
||||
<li>예상 구축 기간: {{ $estimatedMonths }}개월</li>
|
||||
@endif
|
||||
<li>본 견적서의 유효기간은 견적일로부터 30일입니다.</li>
|
||||
<li>세부 사항은 별도 협의를 통해 조정될 수 있습니다.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{{-- 서명 --}}
|
||||
<div style="display: flex; justify-content: flex-end; align-items: center; gap: 24px; margin-top: 48px;">
|
||||
<div style="text-align: right;">
|
||||
<p style="font-size: 16px; font-weight: 600;">(주)코드브릿지엑스</p>
|
||||
<p style="font-size: 12px; color: #6b7280; margin-top: 4px;">대표이사 이의찬 <span class="seal-line"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -4,13 +4,27 @@
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.doc-table { width: 100%; border-collapse: collapse; }
|
||||
.doc-table th, .doc-table td { border: 1px solid #333; padding: 6px 10px; font-size: 13px; }
|
||||
.doc-table th { background-color: #f3f4f6; font-weight: 600; }
|
||||
.text-right { text-align: right; }
|
||||
.text-center { text-align: center; }
|
||||
.text-left { text-align: left; }
|
||||
.seal-box { display: inline-block; width: 60px; height: 60px; border: 2px solid #dc2626; border-radius: 50%; text-align: center; line-height: 56px; color: #dc2626; font-weight: 700; font-size: 16px; }
|
||||
/* 템플릿 선택 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
|
||||
|
||||
@@ -35,201 +49,81 @@
|
||||
$monthlyTotal = $monthlySubtotal + $monthlyVat;
|
||||
|
||||
// 한글 금액 변환
|
||||
function numberToKorean(int $number): string {
|
||||
if ($number === 0) return '영';
|
||||
$units = ['', '만', '억', '조'];
|
||||
$digits = ['', '일', '이', '삼', '사', '오', '육', '칠', '팔', '구'];
|
||||
$subUnits = ['', '십', '백', '천'];
|
||||
if (!function_exists('numberToKorean')) {
|
||||
function numberToKorean(int $number): string {
|
||||
if ($number === 0) return '영';
|
||||
$units = ['', '만', '억', '조'];
|
||||
$digits = ['', '일', '이', '삼', '사', '오', '육', '칠', '팔', '구'];
|
||||
$subUnits = ['', '십', '백', '천'];
|
||||
|
||||
$result = '';
|
||||
$unitIndex = 0;
|
||||
while ($number > 0) {
|
||||
$chunk = $number % 10000;
|
||||
if ($chunk > 0) {
|
||||
$chunkStr = '';
|
||||
$subIndex = 0;
|
||||
$temp = $chunk;
|
||||
while ($temp > 0) {
|
||||
$digit = $temp % 10;
|
||||
if ($digit > 0) {
|
||||
$prefix = ($digit === 1 && $subIndex > 0) ? '' : $digits[$digit];
|
||||
$chunkStr = $prefix . $subUnits[$subIndex] . $chunkStr;
|
||||
$result = '';
|
||||
$unitIndex = 0;
|
||||
while ($number > 0) {
|
||||
$chunk = $number % 10000;
|
||||
if ($chunk > 0) {
|
||||
$chunkStr = '';
|
||||
$subIndex = 0;
|
||||
$temp = $chunk;
|
||||
while ($temp > 0) {
|
||||
$digit = $temp % 10;
|
||||
if ($digit > 0) {
|
||||
$prefix = ($digit === 1 && $subIndex > 0) ? '' : $digits[$digit];
|
||||
$chunkStr = $prefix . $subUnits[$subIndex] . $chunkStr;
|
||||
}
|
||||
$temp = (int)($temp / 10);
|
||||
$subIndex++;
|
||||
}
|
||||
$temp = (int)($temp / 10);
|
||||
$subIndex++;
|
||||
$result = $chunkStr . $units[$unitIndex] . $result;
|
||||
}
|
||||
$result = $chunkStr . $units[$unitIndex] . $result;
|
||||
$number = (int)($number / 10000);
|
||||
$unitIndex++;
|
||||
}
|
||||
$number = (int)($number / 10000);
|
||||
$unitIndex++;
|
||||
return $result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
$devTotalKorean = numberToKorean($devSubtotal);
|
||||
|
||||
// 필수 → 선택 순으로 정렬된 품목
|
||||
$sortedItems = $quotation->items->sortByDesc('is_required')->values();
|
||||
|
||||
// 템플릿 (기본값: classic)
|
||||
$template = $template ?? 'classic';
|
||||
$templates = [
|
||||
'classic' => '클래식',
|
||||
'modern' => '모던',
|
||||
'blue' => '블루',
|
||||
'dark' => '다크',
|
||||
'colorful' => '컬러풀',
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="document-page max-w-[210mm] mx-auto my-8 bg-white shadow-lg" style="padding: 15mm 20mm;">
|
||||
|
||||
{{-- 제목 --}}
|
||||
<h1 class="text-center text-3xl font-bold tracking-[0.5em] mb-8 pb-4 border-b-2 border-gray-800">
|
||||
견 적 서
|
||||
</h1>
|
||||
|
||||
{{-- 견적 정보 --}}
|
||||
<div class="flex justify-between mb-6 text-sm">
|
||||
<div>
|
||||
<p><span class="font-semibold">견적번호:</span> {{ $quotationNo }}</p>
|
||||
<p><span class="font-semibold">유효기간:</span> 견적일로부터 30일</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p><span class="font-semibold">견적일자:</span> {{ $quotation->created_at->format('Y년 m월 d일') }}</p>
|
||||
</div>
|
||||
{{-- 템플릿 선택 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>
|
||||
|
||||
{{-- 수신 / 공급자 --}}
|
||||
<table class="doc-table mb-6">
|
||||
<colgroup>
|
||||
<col style="width: 8%;">
|
||||
<col style="width: 42%;">
|
||||
<col style="width: 8%;">
|
||||
<col style="width: 42%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2" class="text-center" style="background-color: #eff6ff;">수 신</th>
|
||||
<th colspan="2" class="text-center" style="background-color: #f0fdf4;">공 급 자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>귀사명</th>
|
||||
<td>{{ $quotation->title }}</td>
|
||||
<th>상 호</th>
|
||||
<td>(주)코드브릿지엑스</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>업 종</th>
|
||||
<td>{{ $company['industry'] ?? '-' }}</td>
|
||||
<th>대 표</th>
|
||||
<td>이의찬</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>규 모</th>
|
||||
<td>{{ $company['scale'] ?? '-' }}</td>
|
||||
<th>주 소</th>
|
||||
<td>인천 남동구 남동대로 215번길 30</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>현재시스템</th>
|
||||
<td>{{ !empty($company['current_systems']) ? implode(', ', $company['current_systems']) : '-' }}</td>
|
||||
<th>연락처</th>
|
||||
<td>032-123-4567</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{-- 인사말 + 합계 --}}
|
||||
<div class="mb-6 p-4 border-2 border-gray-800 text-center">
|
||||
<p class="text-sm mb-2">아래와 같이 견적합니다.</p>
|
||||
<p class="text-xl font-bold">
|
||||
합계금액: 금 {{ $devTotalKorean }}원정
|
||||
<span class="text-base font-normal">(₩{{ number_format($devSubtotal) }})</span>
|
||||
</p>
|
||||
<p class="text-xs text-gray-600 mt-1">※ 부가가치세 별도 / 월 구독료 {{ number_format($monthlySubtotal) }}원 별도</p>
|
||||
</div>
|
||||
|
||||
{{-- 품목 테이블 --}}
|
||||
<table class="doc-table mb-6">
|
||||
<colgroup>
|
||||
<col style="width: 5%;">
|
||||
<col style="width: 7%;">
|
||||
<col style="width: 20%;">
|
||||
<col style="width: 33%;">
|
||||
<col style="width: 17.5%;">
|
||||
<col style="width: 17.5%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">No</th>
|
||||
<th class="text-center">구분</th>
|
||||
<th class="text-center">품 목</th>
|
||||
<th class="text-center">설 명</th>
|
||||
<th class="text-center">개발비 (원)</th>
|
||||
<th class="text-center">월 구독료 (원)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($sortedItems as $index => $item)
|
||||
<tr>
|
||||
<td class="text-center">{{ $index + 1 }}</td>
|
||||
<td class="text-center">
|
||||
{{ $item->is_required ? '필수' : '선택' }}
|
||||
</td>
|
||||
<td>{{ $item->module_name }}</td>
|
||||
<td class="text-xs">{{ Str::limit($item->reason, 80) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->dev_cost) }}</td>
|
||||
<td class="text-right">{{ number_format((int) $item->monthly_fee) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right">소 계</th>
|
||||
<td class="text-right font-bold">{{ number_format($devSubtotal) }}</td>
|
||||
<td class="text-right font-bold">{{ number_format($monthlySubtotal) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" class="text-right">부가세 (10%)</th>
|
||||
<td class="text-right">{{ number_format($devVat) }}</td>
|
||||
<td class="text-right">{{ number_format($monthlyVat) }}</td>
|
||||
</tr>
|
||||
<tr style="background-color: #f3f4f6;">
|
||||
<th colspan="4" class="text-right text-base">합 계</th>
|
||||
<td class="text-right font-bold text-base">{{ number_format($devTotal) }}</td>
|
||||
<td class="text-right font-bold text-base">{{ number_format($monthlyTotal) }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{-- 비고 --}}
|
||||
<div class="mb-8">
|
||||
<table class="doc-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-left">비 고</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-sm leading-relaxed" style="padding: 12px 16px;">
|
||||
<ol class="list-decimal list-inside space-y-1">
|
||||
<li>상기 금액은 부가가치세 별도입니다.</li>
|
||||
<li>개발비 납부 조건: 계약 시 50%, 완료 시 50% 분할 납부</li>
|
||||
<li>월 구독료: 서비스 오픈일부터 과금 (월 {{ number_format($monthlyTotal) }}원, VAT 포함)</li>
|
||||
@if($estimatedMonths)
|
||||
<li>예상 구축 기간: {{ $estimatedMonths }}개월</li>
|
||||
@endif
|
||||
<li>본 견적서의 유효기간은 견적일로부터 30일입니다.</li>
|
||||
<li>세부 사항은 별도 협의를 통해 조정될 수 있습니다.</li>
|
||||
</ol>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- 서명 --}}
|
||||
<div class="flex justify-end items-center gap-6 mt-12">
|
||||
<div class="text-right">
|
||||
<p class="text-lg font-bold mb-1">(주)코드브릿지엑스</p>
|
||||
<p class="text-sm text-gray-600">대표이사 이 의 찬</p>
|
||||
</div>
|
||||
<div class="seal-box">(인)</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- 선택된 템플릿 렌더링 --}}
|
||||
@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,
|
||||
])
|
||||
@endsection
|
||||
|
||||
Reference in New Issue
Block a user