refactor(WEB): 회계/견적/설정/생산 등 전반적 코드 개선 및 공통화 2차

- 회계 모듈 전면 개선: 청구/입금/출금/매입/매출/세금계산서/일반전표/거래처원장 등
- 견적 모듈 금액 포맷/할인/수식/미리보기 등 코드 정리
- 설정 모듈: 계정관리/직급/직책/권한 상세 간소화
- 생산 모듈: 작업지시서/작업자화면/검수 문서 코드 정리
- UniversalListPage 엑셀 다운로드 및 필터 기능 확장
- 대시보드/게시판/수주 등 날짜 유틸 공통화 적용
- claudedocs 문서 인덱스 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-20 10:45:47 +09:00
parent 71352923c8
commit f344dc7d00
123 changed files with 877 additions and 789 deletions

View File

@@ -39,7 +39,7 @@ import { toast } from "sonner";
import { IntegratedDetailTemplate } from "@/components/templates/IntegratedDetailTemplate";
import { orderSalesConfig } from "./orderSalesConfig";
import { BadgeSm } from "@/components/atoms/BadgeSm";
import { formatAmount } from "@/lib/utils/amount";
import { formatAmount, formatNumber } from "@/lib/utils/amount";
import {
OrderItem,
getOrderById,
@@ -196,7 +196,7 @@ export function OrderSalesDetailEdit({ orderId }: OrderSalesDetailEditProps) {
const upperUnit = (unit || "").toUpperCase();
if (countableUnits.includes(upperUnit)) {
return Math.round(quantity).toLocaleString();
return formatNumber(Math.round(quantity));
}
const rounded = Math.round(quantity * 10000) / 10000;

View File

@@ -3,6 +3,7 @@
import { executeServerAction } from '@/lib/api/execute-server-action';
import { buildApiUrl } from '@/lib/api/query-params';
import type { PaginatedApiResponse } from '@/lib/api/types';
import { formatDate } from '@/lib/utils/date';
// ============================================================================
// API 타입 정의
@@ -517,7 +518,7 @@ function transformApiToFrontend(apiData: ApiOrder): Order {
lotNumber: apiData.order_no,
quoteNumber: apiData.quote?.quote_number || '',
quoteId: apiData.quote_id ?? undefined,
orderDate: apiData.received_at || apiData.created_at.split('T')[0],
orderDate: apiData.received_at || formatDate(apiData.created_at),
client: apiData.client_name || apiData.client?.name || '',
clientId: apiData.client_id ?? undefined,
siteName: apiData.site_name || '',

View File

@@ -7,7 +7,7 @@
* - DocumentHeader: simple 레이아웃 (결재란 없음)
*/
import { formatAmount } from "@/lib/utils/amount";
import { formatAmount, formatNumber } from "@/lib/utils/amount";
import { OrderItem } from "../actions";
import { DocumentHeader } from "@/components/document-system";
@@ -15,7 +15,7 @@ import { DocumentHeader } from "@/components/document-system";
* 수량 포맷 함수 (정수로 표시)
*/
function formatQuantity(quantity: number): string {
return Math.round(quantity).toLocaleString();
return formatNumber(Math.round(quantity));
}
// 제품 정보 타입

View File

@@ -7,6 +7,7 @@
import { getTodayString } from "@/lib/utils/date";
import { OrderItem } from "../actions";
import { formatNumber } from '@/lib/utils/amount';
/**
* 수량 포맷 함수
@@ -18,7 +19,7 @@ function formatQuantity(quantity: number, unit?: string): string {
const upperUnit = (unit || "").toUpperCase();
if (countableUnits.includes(upperUnit)) {
return Math.round(quantity).toLocaleString();
return formatNumber(Math.round(quantity));
}
const rounded = Math.round(quantity * 10000) / 10000;

View File

@@ -12,6 +12,7 @@ import { getTodayString } from "@/lib/utils/date";
import { OrderItem } from "../actions";
import { ProductInfo } from "./OrderDocumentModal";
import { ConstructionApprovalTable } from "@/components/document-system";
import { formatNumber } from '@/lib/utils/amount';
interface SalesOrderDocumentProps {
documentNumber?: string;
@@ -270,10 +271,10 @@ export function SalesOrderDocument({
<td className={tdCenter}>{row.no}</td>
<td className={tdCenter}>{row.type}</td>
<td className={tdCenter}>{row.code}</td>
<td className={tdCenter}>{row.openW.toLocaleString()}</td>
<td className={tdCenter}>{row.openH.toLocaleString()}</td>
<td className={tdCenter}>{row.madeW.toLocaleString()}</td>
<td className={tdCenter}>{row.madeH.toLocaleString()}</td>
<td className={tdCenter}>{formatNumber(row.openW)}</td>
<td className={tdCenter}>{formatNumber(row.openH)}</td>
<td className={tdCenter}>{formatNumber(row.madeW)}</td>
<td className={tdCenter}>{formatNumber(row.madeH)}</td>
<td className={tdCenter}>{row.guideRail}</td>
<td className={tdCenter}>{row.shaft}</td>
<td className={tdCenter}>{row.caseInch}</td>
@@ -319,10 +320,10 @@ export function SalesOrderDocument({
<tr key={row.no} className="border-b border-gray-300">
<td className={tdCenter}>{row.no}</td>
<td className={tdCenter}>{row.code}</td>
<td className={tdCenter}>{row.openW.toLocaleString()}</td>
<td className={tdCenter}>{row.openH.toLocaleString()}</td>
<td className={tdCenter}>{row.madeW.toLocaleString()}</td>
<td className={tdCenter}>{row.madeH.toLocaleString()}</td>
<td className={tdCenter}>{formatNumber(row.openW)}</td>
<td className={tdCenter}>{formatNumber(row.openH)}</td>
<td className={tdCenter}>{formatNumber(row.madeW)}</td>
<td className={tdCenter}>{formatNumber(row.madeH)}</td>
<td className={tdCenter}>{row.guideRail}</td>
<td className={tdCenter}>{row.shaft}</td>
<td className={tdCenter}>{row.jointBar}</td>

View File

@@ -7,7 +7,7 @@
* - DocumentHeader: simple 레이아웃 (결재란 없음)
*/
import { formatAmount } from "@/lib/utils/amount";
import { formatAmount, formatNumber } from "@/lib/utils/amount";
import { OrderItem } from "../actions";
import { DocumentHeader } from "@/components/document-system";
@@ -21,7 +21,7 @@ function formatQuantity(quantity: number, unit?: string): string {
const upperUnit = (unit || "").toUpperCase();
if (countableUnits.includes(upperUnit)) {
return Math.round(quantity).toLocaleString();
return formatNumber(Math.round(quantity));
}
const rounded = Math.round(quantity * 10000) / 10000;