diff --git a/src/app/.DS_Store b/src/app/.DS_Store
new file mode 100644
index 00000000..e26ff0f2
Binary files /dev/null and b/src/app/.DS_Store differ
diff --git a/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx b/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx
index b680f045..4b9d6295 100644
--- a/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx
+++ b/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx
@@ -775,31 +775,35 @@ export default function OrderDetailPage() {
/>
{/* 문서 모달 */}
-
+ {order && (
+
+ )}
- {/* 취소 확인 다이얼로그 */}
+ {/* 다이얼로그들 */}
+ {order && (
+ <>
+ >
+ )}
>
);
}
\ No newline at end of file
diff --git a/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx b/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx
index 519bfc5d..c8cfb6df 100644
--- a/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx
+++ b/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx
@@ -71,9 +71,12 @@ function getOrderStatusBadge(status: OrderStatus) {
order_confirmed: { label: "수주확정", variant: "default", className: "bg-gray-100 text-gray-700 border-gray-200" },
production_ordered: { label: "생산지시완료", variant: "default", className: "bg-blue-100 text-blue-700 border-blue-200" },
in_production: { label: "생산중", variant: "default", className: "bg-green-100 text-green-700 border-green-200" },
+ produced: { label: "생산완료", variant: "default", className: "bg-blue-100 text-blue-700 border-blue-200" },
rework: { label: "재작업중", variant: "default", className: "bg-orange-100 text-orange-700 border-orange-200" },
work_completed: { label: "작업완료", variant: "default", className: "bg-blue-600 text-white border-blue-600" },
+ shipping: { label: "출하중", variant: "default", className: "bg-purple-100 text-purple-700 border-purple-200" },
shipped: { label: "출하완료", variant: "default", className: "bg-gray-500 text-white border-gray-500" },
+ completed: { label: "완료", variant: "default", className: "bg-gray-500 text-white border-gray-500" },
cancelled: { label: "취소", variant: "default", className: "bg-red-100 text-red-700 border-red-200" },
};
diff --git a/src/components/.DS_Store b/src/components/.DS_Store
new file mode 100644
index 00000000..81805e17
Binary files /dev/null and b/src/components/.DS_Store differ
diff --git a/src/components/business/CEODashboard/CEODashboard.tsx b/src/components/business/CEODashboard/CEODashboard.tsx
index c72bd8a3..93ef4880 100644
--- a/src/components/business/CEODashboard/CEODashboard.tsx
+++ b/src/components/business/CEODashboard/CEODashboard.tsx
@@ -83,9 +83,9 @@ export function CEODashboard() {
debtCollection: apiData.debtCollection.data ?? mockData.debtCollection,
monthlyExpense: apiData.monthlyExpense.data ?? mockData.monthlyExpense,
cardManagement: apiData.cardManagement.data ?? mockData.cardManagement,
- // Phase 2 섹션들
- todayIssue: apiData.statusBoard.data ?? mockData.todayIssue,
- todayIssueList: todayIssueData.data?.items ?? mockData.todayIssueList,
+ // Phase 2 섹션들 (API 연동 완료 - 목업 fallback 제거)
+ todayIssue: apiData.statusBoard.data ?? [],
+ todayIssueList: todayIssueData.data?.items ?? [],
calendarSchedules: calendarData.data?.items ?? mockData.calendarSchedules,
vat: vatData.data ?? mockData.vat,
entertainment: entertainmentData.data ?? mockData.entertainment,
diff --git a/src/components/business/CEODashboard/mockData.ts b/src/components/business/CEODashboard/mockData.ts
index b25cb398..decf1a2c 100644
--- a/src/components/business/CEODashboard/mockData.ts
+++ b/src/components/business/CEODashboard/mockData.ts
@@ -5,308 +5,9 @@ import type { CEODashboardData } from './types';
* TODO: API 연동 시 이 파일을 API 호출로 대체
*/
export const mockData: CEODashboardData = {
- todayIssue: [
- { id: '1', label: '수주', count: 3, path: '/sales/order-management-sales', isHighlighted: false },
- { id: '2', label: '채권 추심', count: 3, path: '/accounting/bad-debt-collection', isHighlighted: false },
- { id: '3', label: '안전 재고', count: 3, path: '/material/stock-status', isHighlighted: true },
- { id: '4', label: '세금 신고', count: '부가세 신고 D-15', path: '/accounting/tax', isHighlighted: false },
- { id: '5', label: '신규 업체 등록', count: 3, path: '/accounting/vendors', isHighlighted: false },
- { id: '6', label: '연차', count: 3, path: '/hr/vacation-management', isHighlighted: false },
- { id: '7', label: '발주', count: 3, path: '/construction/order/order-management', isHighlighted: false },
- { id: '8', label: '결재 요청', count: 3, path: '/approval/inbox', isHighlighted: false },
- ],
- todayIssueList: [
- {
- id: 'til1',
- badge: '수주 성공',
- content: 'A전자 신규 수주 450,000,000원 확정',
- time: '10분 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/sales/order-management-sales',
- },
- {
- id: 'til2',
- badge: '주식 이슈',
- content: 'B물산 미수금 15,000,000원 연체 15일',
- time: '1시간 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/accounting/receivables-status',
- },
- {
- id: 'til3',
- badge: '직정 제고',
- content: '원자재 3종 안전재고 미달',
- time: '20시간 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/material/stock-status',
- },
- {
- id: 'til4',
- badge: '지출예상내역서',
- content: '품의서명 외 5건 (2,500,000원)',
- time: '20시간 전',
- date: '2026-01-16',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til5',
- badge: '세금 신고',
- content: '4분기 부가세 신고 D-15',
- time: '20시간 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/accounting/tax',
- },
- {
- id: 'til6',
- badge: '결재 요청',
- content: '법인카드 사용 내역 승인 요청 (김철수)',
- time: '30분 전',
- date: '2026-01-16',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til7',
- badge: '수주 성공',
- content: 'C건설 추가 발주 120,000,000원 확정',
- time: '2시간 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/sales/order-management-sales',
- },
- {
- id: 'til8',
- badge: '기타',
- content: '신규 거래처 D산업 등록 완료',
- time: '3시간 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/accounting/vendors',
- },
- {
- id: 'til9',
- badge: '결재 요청',
- content: '출장비 정산 승인 요청 (이영희)',
- time: '4시간 전',
- date: '2026-01-16',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til10',
- badge: '주식 이슈',
- content: 'E물류 미수금 8,500,000원 연체 7일',
- time: '5시간 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/accounting/receivables-status',
- },
- {
- id: 'til11',
- badge: '직정 제고',
- content: '부품 A-102 재고 부족 경고',
- time: '6시간 전',
- date: '2026-01-16',
- needsApproval: false,
- path: '/material/stock-status',
- },
- {
- id: 'til12',
- badge: '지출예상내역서',
- content: '장비 구매 품의서 (15,000,000원)',
- time: '8시간 전',
- date: '2026-01-16',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til13',
- badge: '수주 성공',
- content: 'F테크 유지보수 계약 연장 85,000,000원',
- time: '어제',
- date: '2026-01-15',
- needsApproval: false,
- path: '/sales/order-management-sales',
- },
- {
- id: 'til14',
- badge: '세금 신고',
- content: '원천세 신고 완료',
- time: '어제',
- date: '2026-01-15',
- needsApproval: false,
- path: '/accounting/tax',
- },
- {
- id: 'til15',
- badge: '결재 요청',
- content: '연차 사용 승인 요청 (박지민 외 2명)',
- time: '어제',
- date: '2026-01-15',
- needsApproval: true,
- path: '/hr/vacation-management',
- },
- // 추가 데이터 (스크롤 테스트용)
- {
- id: 'til16',
- badge: '수주 성공',
- content: 'G산업 신규 계약 250,000,000원 확정',
- time: '2일 전',
- date: '2026-01-14',
- needsApproval: false,
- path: '/sales/order-management-sales',
- },
- {
- id: 'til17',
- badge: '주식 이슈',
- content: 'H물류 미수금 12,000,000원 연체 30일',
- time: '2일 전',
- date: '2026-01-14',
- needsApproval: false,
- path: '/accounting/receivables-status',
- },
- {
- id: 'til18',
- badge: '직정 제고',
- content: '원자재 B-205 안전재고 미달 경고',
- time: '2일 전',
- date: '2026-01-14',
- needsApproval: false,
- path: '/material/stock-status',
- },
- {
- id: 'til19',
- badge: '지출예상내역서',
- content: '사무용품 구매 품의서 (500,000원)',
- time: '2일 전',
- date: '2026-01-14',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til20',
- badge: '세금 신고',
- content: '법인세 중간예납 D-30',
- time: '2일 전',
- date: '2026-01-14',
- needsApproval: false,
- path: '/accounting/tax',
- },
- {
- id: 'til21',
- badge: '결재 요청',
- content: '해외출장 경비 승인 요청 (최민수)',
- time: '3일 전',
- date: '2026-01-13',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til22',
- badge: '수주 성공',
- content: 'I테크 추가 발주 80,000,000원 확정',
- time: '3일 전',
- date: '2026-01-13',
- needsApproval: false,
- path: '/sales/order-management-sales',
- },
- {
- id: 'til23',
- badge: '기타',
- content: '신규 거래처 J전자 등록 완료',
- time: '3일 전',
- date: '2026-01-13',
- needsApproval: false,
- path: '/accounting/vendors',
- },
- {
- id: 'til24',
- badge: '주식 이슈',
- content: 'K상사 미수금 5,000,000원 연체 45일',
- time: '3일 전',
- date: '2026-01-13',
- needsApproval: false,
- path: '/accounting/receivables-status',
- },
- {
- id: 'til25',
- badge: '직정 제고',
- content: '완제품 C-301 재고 부족 경고',
- time: '4일 전',
- date: '2026-01-12',
- needsApproval: false,
- path: '/material/stock-status',
- },
- {
- id: 'til26',
- badge: '지출예상내역서',
- content: '마케팅 비용 품의서 (3,000,000원)',
- time: '4일 전',
- date: '2026-01-12',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til27',
- badge: '결재 요청',
- content: '복리후생비 사용 승인 요청 (정영수)',
- time: '4일 전',
- date: '2026-01-12',
- needsApproval: true,
- path: '/approval/inbox',
- },
- {
- id: 'til28',
- badge: '수주 성공',
- content: 'L건설 유지보수 계약 연장 45,000,000원',
- time: '5일 전',
- date: '2026-01-11',
- needsApproval: false,
- path: '/sales/order-management-sales',
- },
- {
- id: 'til29',
- badge: '기타',
- content: '사내 시스템 업데이트 완료',
- time: '5일 전',
- date: '2026-01-11',
- needsApproval: false,
- path: '/settings',
- },
- {
- id: 'til30',
- badge: '세금 신고',
- content: '지방세 납부 완료',
- time: '5일 전',
- date: '2026-01-11',
- needsApproval: false,
- path: '/accounting/tax',
- },
- // 1월 6일 (기획서 스크린샷 날짜) 이슈 데이터
- {
- id: 'til31',
- badge: '직정 제고',
- content: '원자재 3종 안전재고 미달',
- time: '10일 전',
- date: '2026-01-06',
- needsApproval: false,
- path: '/material/stock-status',
- },
- {
- id: 'til32',
- badge: '결재 요청',
- content: '출장비 정산 승인 요청',
- time: '10일 전',
- date: '2026-01-06',
- needsApproval: true,
- path: '/approval/inbox',
- },
- ],
+ // TodayIssue: API 연동 완료 - 목업 데이터 제거됨
+ todayIssue: [],
+ todayIssueList: [],
dailyReport: {
date: '2026년 1월 5일 월요일',
cards: [
diff --git a/src/components/business/CEODashboard/sections/TodayIssueSection.tsx b/src/components/business/CEODashboard/sections/TodayIssueSection.tsx
index 9dae9f72..65b1b53d 100644
--- a/src/components/business/CEODashboard/sections/TodayIssueSection.tsx
+++ b/src/components/business/CEODashboard/sections/TodayIssueSection.tsx
@@ -155,9 +155,9 @@ export function TodayIssueSection({ items }: TodayIssueSectionProps) {
{item.time}
- {/* 버튼 */}
+ {/* TODO: 버튼 - API 구현 후 활성화
e.stopPropagation()}>
- {item.needsApproval ? (
+ {item.needsApproval && (
<>
+ */}
))
)}
diff --git a/src/components/orders/actions.ts b/src/components/orders/actions.ts
index 14588f69..7a0f170d 100644
--- a/src/components/orders/actions.ts
+++ b/src/components/orders/actions.ts
@@ -197,10 +197,13 @@ export type OrderStatus =
| 'order_registered' // DRAFT
| 'order_confirmed' // CONFIRMED
| 'production_ordered' // IN_PROGRESS
- | 'in_production' // IN_PROGRESS (세부)
- | 'rework' // IN_PROGRESS (세부)
- | 'work_completed' // IN_PROGRESS (세부)
- | 'shipped' // COMPLETED
+ | 'in_production' // IN_PRODUCTION
+ | 'produced' // PRODUCED
+ | 'shipping' // SHIPPING
+ | 'shipped' // SHIPPED
+ | 'completed' // COMPLETED
+ | 'rework' // (세부 - 레거시)
+ | 'work_completed' // (세부 - 레거시)
| 'cancelled'; // CANCELLED
export interface Order {
@@ -401,7 +404,11 @@ const API_TO_FRONTEND_STATUS: Record = {
'DRAFT': 'order_registered',
'CONFIRMED': 'order_confirmed',
'IN_PROGRESS': 'production_ordered',
- 'COMPLETED': 'shipped',
+ 'IN_PRODUCTION': 'in_production',
+ 'PRODUCED': 'produced',
+ 'SHIPPING': 'shipping',
+ 'SHIPPED': 'shipped',
+ 'COMPLETED': 'completed',
'CANCELLED': 'cancelled',
};
@@ -409,10 +416,13 @@ const FRONTEND_TO_API_STATUS: Record = {
'order_registered': 'DRAFT',
'order_confirmed': 'CONFIRMED',
'production_ordered': 'IN_PROGRESS',
- 'in_production': 'IN_PROGRESS',
+ 'in_production': 'IN_PRODUCTION',
+ 'produced': 'PRODUCED',
+ 'shipping': 'SHIPPING',
+ 'shipped': 'SHIPPED',
+ 'completed': 'COMPLETED',
'rework': 'IN_PROGRESS',
'work_completed': 'IN_PROGRESS',
- 'shipped': 'COMPLETED',
'cancelled': 'CANCELLED',
};
diff --git a/src/lib/.DS_Store b/src/lib/.DS_Store
new file mode 100644
index 00000000..f346b798
Binary files /dev/null and b/src/lib/.DS_Store differ
diff --git a/src/lib/api/dashboard/transformers.ts b/src/lib/api/dashboard/transformers.ts
index f8bc53db..360c2d68 100644
--- a/src/lib/api/dashboard/transformers.ts
+++ b/src/lib/api/dashboard/transformers.ts
@@ -75,6 +75,59 @@ function calculateChangeRate(current: number, previous: number): number {
// 1. DailyReport 변환
// ============================================
+/**
+ * 운영자금 안정성에 따른 색상 반환
+ * 참조: AI 리포트 색상 체계 가이드 - 섹션 2.3
+ */
+function getStabilityColor(stability: string): 'red' | 'green' | 'blue' {
+ switch (stability) {
+ case 'stable':
+ return 'blue'; // 6개월 이상 - 안정적
+ case 'caution':
+ return 'green'; // 3-6개월 - 주의 (주황 대신 green 사용, 기존 타입 호환)
+ case 'warning':
+ return 'red'; // 3개월 미만 - 경고
+ default:
+ return 'blue';
+ }
+}
+
+/**
+ * 운영자금 안정성 메시지 생성
+ * - 음수: 현금성 자산 적자 상태
+ * - 0~3개월: 자금 부족 우려
+ * - 3~6개월: 자금 관리 필요
+ * - 6개월 이상: 안정적
+ */
+function getStabilityMessage(months: number | null, stability: string, cashAsset: number): string {
+ if (months === null) {
+ return '월 운영비 데이터가 없어 안정성을 판단할 수 없습니다.';
+ }
+
+ // 현금성 자산이 음수인 경우 (적자 상태)
+ if (cashAsset < 0 || months < 0) {
+ return '현금성 자산이 부족한 상태입니다. 긴급 자금 확보가 필요합니다.';
+ }
+
+ // 운영 가능 기간이 거의 없는 경우 (1개월 미만)
+ if (months < 1) {
+ return '운영 자금이 거의 소진된 상태입니다. 즉시 자금 확보가 필요합니다.';
+ }
+
+ const monthsText = `${months}개월분`;
+
+ switch (stability) {
+ case 'stable':
+ return `월 운영비용 대비 ${monthsText}이 확보되어 안정적입니다.`;
+ case 'caution':
+ return `월 운영비용 대비 ${monthsText}이 확보되어 있습니다. 자금 관리가 필요합니다.`;
+ case 'warning':
+ return `월 운영비용 대비 ${monthsText}만 확보되어 자금 부족 우려가 있습니다.`;
+ default:
+ return `월 운영비용 대비 ${monthsText}이 확보되어 있습니다.`;
+ }
+}
+
/**
* 일일 일보 CheckPoints 생성
* 참조: AI 리포트 색상 체계 가이드 - 섹션 2
@@ -109,15 +162,37 @@ function generateDailyReportCheckPoints(api: DailyReportApiResponse): CheckPoint
});
}
- // 현금성 자산 현황
+ // 현금성 자산 + 운영자금 안정성 현황
const cashAsset = api.cash_asset_total;
+ const operatingMonths = api.operating_months;
+ const operatingStability = api.operating_stability;
+ const stabilityColor = getStabilityColor(operatingStability);
+ const stabilityMessage = getStabilityMessage(operatingMonths, operatingStability, cashAsset);
+
+ // 하이라이트 생성 (음수/적자 상태일 때는 "X개월분" 대신 다른 메시지)
+ const isDeficit = cashAsset < 0 || (operatingMonths !== null && operatingMonths < 0);
+ const isAlmostEmpty = operatingMonths !== null && operatingMonths >= 0 && operatingMonths < 1;
+
+ const highlights: Array<{ text: string; color: 'red' | 'green' | 'blue' }> = [];
+
+ if (isDeficit) {
+ highlights.push({ text: '긴급 자금 확보 필요', color: 'red' });
+ } else if (isAlmostEmpty) {
+ highlights.push({ text: '즉시 자금 확보 필요', color: 'red' });
+ } else if (operatingMonths !== null && operatingMonths >= 1) {
+ highlights.push({ text: `${operatingMonths}개월분`, color: stabilityColor });
+ if (operatingStability === 'stable') {
+ highlights.push({ text: '안정적', color: 'blue' });
+ } else if (operatingStability === 'warning') {
+ highlights.push({ text: '자금 부족 우려', color: 'red' });
+ }
+ }
+
checkPoints.push({
id: 'dr-cash-asset',
- type: 'info' as CheckPointType,
- message: `총 현금성 자산이 ${formatAmount(cashAsset)}입니다.`,
- highlights: [
- { text: formatAmount(cashAsset), color: 'blue' as const },
- ],
+ type: isDeficit || isAlmostEmpty ? 'warning' as CheckPointType : 'info' as CheckPointType,
+ message: `총 현금성 자산이 ${formatAmount(cashAsset)}입니다. ${stabilityMessage}`,
+ highlights,
});
return checkPoints;
diff --git a/src/lib/api/dashboard/types.ts b/src/lib/api/dashboard/types.ts
index 2cddb9c1..1f3d6555 100644
--- a/src/lib/api/dashboard/types.ts
+++ b/src/lib/api/dashboard/types.ts
@@ -16,6 +16,9 @@ export interface CurrencyTotals {
balance: number; // 잔액
}
+/** 운영자금 안정성 상태 */
+export type OperatingStability = 'stable' | 'caution' | 'warning' | 'unknown';
+
/** GET /api/proxy/daily-report/summary 응답 */
export interface DailyReportApiResponse {
date: string; // "2026-01-20"
@@ -25,6 +28,10 @@ export interface DailyReportApiResponse {
cash_asset_total: number; // 현금성 자산 합계
krw_totals: CurrencyTotals; // 원화 합계
usd_totals: CurrencyTotals; // 달러 합계
+ // 운영자금 안정성 지표
+ monthly_operating_expense: number; // 월 운영비 (직전 3개월 평균)
+ operating_months: number | null; // 운영 가능 개월 수
+ operating_stability: OperatingStability; // 안정성 상태
}
// ============================================