refactor(WEB): 회계/견적/설정/생산 등 전반적 코드 개선 및 공통화 2차
- 회계 모듈 전면 개선: 청구/입금/출금/매입/매출/세금계산서/일반전표/거래처원장 등 - 견적 모듈 금액 포맷/할인/수식/미리보기 등 코드 정리 - 설정 모듈: 계정관리/직급/직책/권한 상세 간소화 - 생산 모듈: 작업지시서/작업자화면/검수 문서 코드 정리 - UniversalListPage 엑셀 다운로드 및 필터 기능 확장 - 대시보드/게시판/수주 등 날짜 유틸 공통화 적용 - claudedocs 문서 인덱스 업데이트 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { Percent } from "lucide-react";
|
||||
import { formatNumber } from "@/lib/utils/amount";
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
@@ -159,7 +160,7 @@ export function DiscountModal({
|
||||
<div className="space-y-2">
|
||||
<Label>공급가액</Label>
|
||||
<Input
|
||||
value={supplyAmount.toLocaleString()}
|
||||
value={formatNumber(supplyAmount)}
|
||||
disabled
|
||||
className="bg-gray-50 text-right font-medium"
|
||||
/>
|
||||
@@ -189,7 +190,7 @@ export function DiscountModal({
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="0"
|
||||
value={discountAmount ? parseInt(discountAmount).toLocaleString() : ""}
|
||||
value={discountAmount ? formatNumber(parseInt(discountAmount)) : ""}
|
||||
onChange={(e) => handleDiscountAmountChange(e.target.value.replace(/,/g, ""))}
|
||||
className="pr-8 text-right"
|
||||
/>
|
||||
@@ -203,7 +204,7 @@ export function DiscountModal({
|
||||
<div className="space-y-2">
|
||||
<Label>할인 후 공급가액</Label>
|
||||
<Input
|
||||
value={discountedAmount.toLocaleString()}
|
||||
value={formatNumber(discountedAmount)}
|
||||
disabled
|
||||
className="bg-gray-50 text-right font-bold text-blue-600"
|
||||
/>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import { Calculator, ChevronDown, ChevronRight } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { formatNumber } from "@/lib/utils/amount";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -131,11 +132,11 @@ function LocationDetail({ location }: { location: LocationItem }) {
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<span className="text-sm text-gray-600">1개당 </span>
|
||||
<span className="font-bold text-blue-600">{bom.grand_total.toLocaleString()}원</span>
|
||||
<span className="font-bold text-blue-600">{formatNumber(bom.grand_total)}원</span>
|
||||
<span className="mx-2">×</span>
|
||||
<span className="text-sm">{location.quantity}개 =</span>
|
||||
<span className="font-bold text-green-600 text-lg ml-2">
|
||||
{(bom.grand_total * location.quantity).toLocaleString()}원
|
||||
{formatNumber(bom.grand_total * location.quantity)}원
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -212,7 +213,7 @@ function FormulaTable({ formulas, stepName }: { formulas: FormulaItem[]; stepNam
|
||||
<tr key={i} className="border-b hover:bg-gray-50">
|
||||
<td className="p-2 border font-mono font-bold text-blue-600">{f.var}</td>
|
||||
<td className="p-2 border text-gray-600">{f.desc}</td>
|
||||
<td className="p-2 border text-right font-mono">{typeof f.value === 'number' ? f.value.toLocaleString() : f.value}</td>
|
||||
<td className="p-2 border text-right font-mono">{typeof f.value === 'number' ? formatNumber(f.value) : f.value}</td>
|
||||
<td className="p-2 border text-gray-500">{f.unit}</td>
|
||||
</tr>
|
||||
))}
|
||||
@@ -243,7 +244,7 @@ function FormulaTable({ formulas, stepName }: { formulas: FormulaItem[]; stepNam
|
||||
<td className="p-2 border font-mono text-purple-600">{f.formula}</td>
|
||||
<td className="p-2 border font-mono text-gray-600">{f.calculation}</td>
|
||||
<td className="p-2 border text-right">
|
||||
<span className="font-mono font-bold">{typeof f.result === 'number' ? f.result.toLocaleString() : f.result}</span>
|
||||
<span className="font-mono font-bold">{typeof f.result === 'number' ? formatNumber(f.result) : f.result}</span>
|
||||
<span className="text-gray-500 text-xs ml-1">{f.unit}</span>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -273,9 +274,9 @@ function FormulaTable({ formulas, stepName }: { formulas: FormulaItem[]; stepNam
|
||||
<td className="p-2 border font-medium">{f.item}</td>
|
||||
<td className="p-2 border font-mono text-purple-600 text-xs">{f.qty_formula}</td>
|
||||
<td className="p-2 border text-right font-mono">{f.qty_result}</td>
|
||||
<td className="p-2 border text-right font-mono">{f.unit_price?.toLocaleString()}</td>
|
||||
<td className="p-2 border text-right font-mono">{formatNumber(f.unit_price)}</td>
|
||||
<td className="p-2 border font-mono text-gray-600 text-xs">{f.price_calc}</td>
|
||||
<td className="p-2 border text-right font-mono font-bold">{f.total?.toLocaleString()}</td>
|
||||
<td className="p-2 border text-right font-mono font-bold">{formatNumber(f.total)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
@@ -299,7 +300,7 @@ function FormulaTable({ formulas, stepName }: { formulas: FormulaItem[]; stepNam
|
||||
<tr key={i} className="border-b hover:bg-gray-50">
|
||||
<td className="p-2 border font-medium">{f.category}</td>
|
||||
<td className="p-2 border text-gray-600 text-xs">{f.formula}</td>
|
||||
<td className="p-2 border text-right font-mono font-bold">{f.result?.toLocaleString()}원</td>
|
||||
<td className="p-2 border text-right font-mono font-bold">{typeof f.result === 'number' ? formatNumber(f.result) : f.result}원</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { QuoteFormData } from "./types";
|
||||
import type { CompanyFormData } from "@/components/settings/CompanyInfoManagement/types";
|
||||
import { DocumentHeader, LotApprovalTable } from "@/components/document-system";
|
||||
import { formatNumber } from '@/lib/utils/amount';
|
||||
|
||||
interface PurchaseOrderDocumentProps {
|
||||
quote: QuoteFormData;
|
||||
@@ -232,7 +233,7 @@ export function PurchaseOrderDocument({ quote, companyInfo }: PurchaseOrderDocum
|
||||
<td style={{ textAlign: 'center' }}>{item.no}</td>
|
||||
<td>{item.name}</td>
|
||||
<td>{item.spec}</td>
|
||||
<td style={{ textAlign: 'right' }}>{item.length > 0 ? item.length.toLocaleString() : ''}</td>
|
||||
<td style={{ textAlign: 'right' }}>{item.length > 0 ? formatNumber(item.length) : ''}</td>
|
||||
<td style={{ textAlign: 'center', fontWeight: '600' }}>{item.quantity}</td>
|
||||
<td>{item.note}</td>
|
||||
</tr>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { QuoteFormData } from "./types";
|
||||
import type { CompanyFormData } from "@/components/settings/CompanyInfoManagement/types";
|
||||
import { DocumentHeader, SignatureSection } from "@/components/document-system";
|
||||
import { formatNumber } from "@/lib/utils/amount";
|
||||
|
||||
interface QuoteDocumentProps {
|
||||
quote: QuoteFormData;
|
||||
@@ -18,7 +19,7 @@ interface QuoteDocumentProps {
|
||||
export function QuoteDocument({ quote, companyInfo }: QuoteDocumentProps) {
|
||||
const formatAmount = (amount: number | undefined) => {
|
||||
if (amount === undefined || amount === null) return '0';
|
||||
return amount.toLocaleString('ko-KR');
|
||||
return formatNumber(amount);
|
||||
};
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
import { Save, Check, ArrowLeft, Loader2, FileText, Pencil, ClipboardList, Percent, Calculator } from "lucide-react";
|
||||
|
||||
import { Button } from "../ui/button";
|
||||
import { formatNumber } from "@/lib/utils/amount";
|
||||
|
||||
// =============================================================================
|
||||
// Props
|
||||
@@ -92,7 +93,7 @@ export function QuoteFooterBar({
|
||||
<div>
|
||||
<p className="text-xs md:text-sm text-gray-600">예상 전체 견적금액</p>
|
||||
<p className="text-lg md:text-3xl font-bold text-blue-600">
|
||||
{totalAmount.toLocaleString()}
|
||||
{formatNumber(totalAmount)}
|
||||
<span className="text-sm md:text-lg font-normal text-gray-500 ml-1">원</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -226,15 +226,15 @@ export function QuoteManagementClient({
|
||||
// 테이블 컬럼
|
||||
columns: [
|
||||
{ key: 'rowNumber', label: '번호', className: 'w-[60px] text-center' },
|
||||
{ key: 'quoteNumber', label: '견적번호', className: 'min-w-[120px]' },
|
||||
{ key: 'registrationDate', label: '접수일', className: 'w-[100px]' },
|
||||
{ key: 'status', label: '상태', className: 'w-[80px]' },
|
||||
{ key: 'productCategory', label: '제품분류', className: 'w-[100px]' },
|
||||
{ key: 'quantity', label: '수량', className: 'w-[60px] text-center' },
|
||||
{ key: 'amount', label: '금액', className: 'w-[120px] text-right' },
|
||||
{ key: 'client', label: '발주처', className: 'min-w-[100px]' },
|
||||
{ key: 'site', label: '현장명', className: 'min-w-[120px]' },
|
||||
{ key: 'manager', label: '담당자', className: 'w-[80px]' },
|
||||
{ key: 'quoteNumber', label: '견적번호', className: 'min-w-[120px]', sortable: true },
|
||||
{ key: 'registrationDate', label: '접수일', className: 'w-[100px]', sortable: true },
|
||||
{ key: 'status', label: '상태', className: 'w-[80px]', sortable: true },
|
||||
{ key: 'productCategory', label: '제품분류', className: 'w-[100px]', sortable: true },
|
||||
{ key: 'quantity', label: '수량', className: 'w-[60px] text-center', sortable: true },
|
||||
{ key: 'amount', label: '금액', className: 'w-[120px] text-right', sortable: true },
|
||||
{ key: 'client', label: '발주처', className: 'min-w-[100px]', sortable: true },
|
||||
{ key: 'site', label: '현장명', className: 'min-w-[120px]', sortable: true },
|
||||
{ key: 'manager', label: '담당자', className: 'w-[80px]', sortable: true },
|
||||
{ key: 'remarks', label: '비고', className: 'min-w-[150px]' },
|
||||
{ key: 'actions', label: '작업', className: 'w-[100px]' },
|
||||
],
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import type { QuoteFormDataV2 } from './QuoteRegistration';
|
||||
import { formatNumber } from '@/lib/utils/amount';
|
||||
import type { BomCalculationResultItem } from './types';
|
||||
|
||||
// 양식 타입
|
||||
@@ -212,10 +213,10 @@ export function QuotePreviewContent({
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">{loc.quantity}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">SET</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-right">
|
||||
{(loc.unitPrice || 0).toLocaleString()}
|
||||
{formatNumber(loc.unitPrice || 0)}
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">
|
||||
{(loc.totalPrice || 0).toLocaleString()}
|
||||
{formatNumber(loc.totalPrice || 0)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
@@ -231,7 +232,7 @@ export function QuotePreviewContent({
|
||||
</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1"></td>
|
||||
<td className="border-r border-gray-300 px-2 py-1"></td>
|
||||
<td className="px-2 py-1 text-right">{subtotal.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right">{formatNumber(subtotal)}</td>
|
||||
</tr>
|
||||
|
||||
{/* 할인율 */}
|
||||
@@ -250,7 +251,7 @@ export function QuotePreviewContent({
|
||||
할인금액
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">
|
||||
{hasDiscount ? `-${discountAmount.toLocaleString()}` : '0'}
|
||||
{hasDiscount ? `-${formatNumber(discountAmount)}` : '0'}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -259,7 +260,7 @@ export function QuotePreviewContent({
|
||||
<td colSpan={9} className="border-r border-gray-300 px-2 py-1 text-center bg-gray-50">
|
||||
할인 후 금액
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">{afterDiscount.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right">{formatNumber(afterDiscount)}</td>
|
||||
</tr>
|
||||
|
||||
{/* 부가세 포함일 때 추가 행들 */}
|
||||
@@ -269,13 +270,13 @@ export function QuotePreviewContent({
|
||||
<td colSpan={9} className="border-r border-gray-300 px-2 py-1 text-center bg-gray-50">
|
||||
부가가치세 합계
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">{vat.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right">{formatNumber(vat)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colSpan={9} className="border-r border-gray-300 px-2 py-1 text-center bg-gray-50 font-semibold">
|
||||
총 견적금액
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right font-semibold">{grandTotal.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right font-semibold">{formatNumber(grandTotal)}</td>
|
||||
</tr>
|
||||
</>
|
||||
)}
|
||||
@@ -289,7 +290,7 @@ export function QuotePreviewContent({
|
||||
합계금액 ({vatIncluded ? '부가세 포함' : '부가세 별도'})
|
||||
</span>
|
||||
<span className="text-xl font-bold">
|
||||
₩ {grandTotal.toLocaleString()}
|
||||
₩ {formatNumber(grandTotal)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -346,10 +347,10 @@ export function QuotePreviewContent({
|
||||
{item.unit || 'EA'}
|
||||
</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-right">
|
||||
{item.unit_price.toLocaleString()}
|
||||
{formatNumber(item.unit_price)}
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">
|
||||
{item.total_price.toLocaleString()}
|
||||
{formatNumber(item.total_price)}
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
@@ -372,10 +373,10 @@ export function QuotePreviewContent({
|
||||
</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1"></td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-right">
|
||||
{(loc.bomResult?.grand_total || 0).toLocaleString()}
|
||||
{formatNumber(loc.bomResult?.grand_total || 0)}
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right font-semibold">
|
||||
{(locationSubtotal * loc.quantity).toLocaleString()}
|
||||
{formatNumber(locationSubtotal * loc.quantity)}
|
||||
</td>
|
||||
</tr>
|
||||
</React.Fragment>
|
||||
@@ -388,7 +389,7 @@ export function QuotePreviewContent({
|
||||
총 합계
|
||||
</td>
|
||||
<td className="px-2 py-2 text-right font-bold text-lg">
|
||||
{subtotal.toLocaleString()}
|
||||
{formatNumber(subtotal)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -53,6 +53,7 @@ import { useDevFill } from "@/components/dev/useDevFill";
|
||||
import type { Vendor } from "../accounting/VendorManagement";
|
||||
import type { BomMaterial, CalculationResults, BomCalculationResultItem } from "./types";
|
||||
import { getLocalDateString, getDateAfterDays } from "@/lib/utils/date";
|
||||
import { formatNumber } from "@/lib/utils/amount";
|
||||
|
||||
// =============================================================================
|
||||
// 타입 정의
|
||||
@@ -322,7 +323,7 @@ export function QuoteRegistration({
|
||||
// 할인 적용 핸들러
|
||||
const handleApplyDiscount = useCallback((rate: number, amount: number) => {
|
||||
setFormData(prev => ({ ...prev, discountRate: rate, discountAmount: amount }));
|
||||
toast.success(`할인이 적용되었습니다. (${rate.toFixed(1)}%, ${amount.toLocaleString()}원)`);
|
||||
toast.success(`할인이 적용되었습니다. (${rate.toFixed(1)}%, ${formatNumber(amount)}원)`);
|
||||
}, []);
|
||||
|
||||
// 개소별 합계
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useMemo } from "react";
|
||||
import { Coins } from "lucide-react";
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "../ui/card";
|
||||
import { formatNumber } from "@/lib/utils/amount";
|
||||
|
||||
import type { LocationItem } from "./QuoteRegistration";
|
||||
|
||||
@@ -175,11 +176,11 @@ export function QuoteSummaryPanel({
|
||||
<div className="text-right">
|
||||
<p className="text-xs text-gray-500">상세소계</p>
|
||||
<p className="font-bold text-blue-600">
|
||||
{loc.totalPrice.toLocaleString()}
|
||||
{formatNumber(loc.totalPrice)}
|
||||
</p>
|
||||
{loc.unitPrice > 0 && (
|
||||
<p className="text-xs text-gray-400">
|
||||
수량 적용: {(loc.unitPrice * loc.quantity).toLocaleString()}
|
||||
수량 적용: {formatNumber(loc.unitPrice * loc.quantity)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
@@ -221,7 +222,7 @@ export function QuoteSummaryPanel({
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-gray-500">({category.count}개)</span>
|
||||
<span className="font-bold text-blue-600">
|
||||
{category.amount.toLocaleString()}
|
||||
{formatNumber(category.amount)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -232,11 +233,11 @@ export function QuoteSummaryPanel({
|
||||
<div>
|
||||
<span className="text-sm text-gray-700">{item.name}</span>
|
||||
<p className="text-xs text-gray-400">
|
||||
수량: {item.quantity} × 단가: {item.unitPrice.toLocaleString()}
|
||||
수량: {item.quantity} × 단가: {formatNumber(item.unitPrice)}
|
||||
</p>
|
||||
</div>
|
||||
<span className="text-sm font-medium text-blue-600">
|
||||
{item.totalPrice.toLocaleString()}
|
||||
{formatNumber(item.totalPrice)}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
@@ -258,7 +259,7 @@ export function QuoteSummaryPanel({
|
||||
<div>
|
||||
<p className="text-sm text-gray-400">예상 견적금액</p>
|
||||
<p className="text-4xl font-bold text-blue-400">
|
||||
{totalAmount.toLocaleString()}
|
||||
{formatNumber(totalAmount)}
|
||||
<span className="text-xl ml-1">원</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
import { DocumentViewer } from '@/components/document-system';
|
||||
import { getTodayString } from '@/lib/utils/date';
|
||||
import { formatNumber } from '@/lib/utils/amount';
|
||||
import type { QuoteFormDataV2 } from './QuoteRegistration';
|
||||
|
||||
interface QuoteTransactionModalProps {
|
||||
@@ -222,10 +223,10 @@ export function QuoteTransactionModal({
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">{loc.quantity || 1}</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-center">SET</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1 text-right">
|
||||
{(loc.unitPrice || 0).toLocaleString()}
|
||||
{formatNumber(loc.unitPrice || 0)}
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">
|
||||
{(loc.totalPrice || 0).toLocaleString()}
|
||||
{formatNumber(loc.totalPrice || 0)}
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
@@ -248,7 +249,7 @@ export function QuoteTransactionModal({
|
||||
</td>
|
||||
<td className="border-r border-gray-300 px-2 py-1"></td>
|
||||
<td className="border-r border-gray-300 px-2 py-1"></td>
|
||||
<td className="px-2 py-1 text-right">{subtotal.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right">{formatNumber(subtotal)}</td>
|
||||
</tr>
|
||||
|
||||
{/* 할인율 */}
|
||||
@@ -267,7 +268,7 @@ export function QuoteTransactionModal({
|
||||
할인금액
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">
|
||||
{hasDiscount ? discountAmount.toLocaleString() : '0'}
|
||||
{hasDiscount ? formatNumber(discountAmount) : '0'}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -276,7 +277,7 @@ export function QuoteTransactionModal({
|
||||
<td colSpan={9} className="border-r border-gray-300 px-2 py-1 text-center bg-gray-50">
|
||||
할인 후 금액
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">{afterDiscount.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right">{formatNumber(afterDiscount)}</td>
|
||||
</tr>
|
||||
|
||||
{/* 부가세 포함일 때 추가 행들 */}
|
||||
@@ -286,13 +287,13 @@ export function QuoteTransactionModal({
|
||||
<td colSpan={9} className="border-r border-gray-300 px-2 py-1 text-center bg-gray-50">
|
||||
부가가치세 합계
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right">{vat.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right">{formatNumber(vat)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colSpan={9} className="border-r border-gray-300 px-2 py-1 text-center bg-gray-50 font-semibold">
|
||||
총 금액
|
||||
</td>
|
||||
<td className="px-2 py-1 text-right font-semibold">{grandTotal.toLocaleString()}</td>
|
||||
<td className="px-2 py-1 text-right font-semibold">{formatNumber(grandTotal)}</td>
|
||||
</tr>
|
||||
</>
|
||||
)}
|
||||
@@ -306,7 +307,7 @@ export function QuoteTransactionModal({
|
||||
합계금액 ({vatIncluded ? '부가세 포함' : '부가세 별도'})
|
||||
</span>
|
||||
<span className="text-xl font-bold">
|
||||
₩ {grandTotal.toLocaleString()}
|
||||
₩ {formatNumber(grandTotal)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user