'use server'; import { isNextRedirectError } from '@/lib/utils/redirect-error'; import { cookies } from 'next/headers'; import { executeServerAction, type ActionResult } from '@/lib/api/execute-server-action'; import type { NoteReceivableItem, DailyAccountItem, MatchStatus } from './types'; const API_URL = process.env.NEXT_PUBLIC_API_URL; // ===== API 응답 타입 ===== interface NoteReceivableItemApi { id: string; content: string; current_balance: number; issue_date: string; due_date: string; } interface DailyAccountItemApi { id: string; category: string; match_status: MatchStatus; carryover: number; income: number; expense: number; balance: number; currency: 'KRW' | 'USD'; } interface DailyReportSummaryApi { date: string; day_of_week: string; note_receivable_total: number; foreign_currency_total: number; cash_asset_total: number; krw_totals: { carryover: number; income: number; expense: number; balance: number }; usd_totals: { carryover: number; income: number; expense: number; balance: number }; } // ===== API → Frontend 변환 ===== function transformNoteReceivable(item: NoteReceivableItemApi): NoteReceivableItem { return { id: item.id, content: item.content, currentBalance: item.current_balance, issueDate: item.issue_date, dueDate: item.due_date, }; } function transformDailyAccount(item: DailyAccountItemApi): DailyAccountItem { return { id: item.id, category: item.category, matchStatus: item.match_status, carryover: item.carryover, income: item.income, expense: item.expense, balance: item.balance, currency: item.currency, }; } // ===== 어음 및 외상매출채권 현황 조회 ===== export async function getNoteReceivables(params?: { date?: string; }): Promise<{ success: boolean; data: NoteReceivableItem[]; error?: string }> { const searchParams = new URLSearchParams(); if (params?.date) searchParams.set('date', params.date); const queryString = searchParams.toString(); const result = await executeServerAction({ url: `${API_URL}/api/v1/daily-report/note-receivables${queryString ? `?${queryString}` : ''}`, transform: (data: NoteReceivableItemApi[]) => (data || []).map(transformNoteReceivable), errorMessage: '어음 현황 조회에 실패했습니다.', }); return { success: result.success, data: result.data || [], error: result.error }; } // ===== 일별 계좌 현황 조회 ===== export async function getDailyAccounts(params?: { date?: string; }): Promise<{ success: boolean; data: DailyAccountItem[]; error?: string }> { const searchParams = new URLSearchParams(); if (params?.date) searchParams.set('date', params.date); const queryString = searchParams.toString(); const result = await executeServerAction({ url: `${API_URL}/api/v1/daily-report/daily-accounts${queryString ? `?${queryString}` : ''}`, transform: (data: DailyAccountItemApi[]) => (data || []).map(transformDailyAccount), errorMessage: '계좌 현황 조회에 실패했습니다.', }); return { success: result.success, data: result.data || [], error: result.error }; } // ===== 일일 보고서 요약 조회 ===== export async function getDailyReportSummary(params?: { date?: string; }): Promise> { const searchParams = new URLSearchParams(); if (params?.date) searchParams.set('date', params.date); const queryString = searchParams.toString(); return executeServerAction({ url: `${API_URL}/api/v1/daily-report/summary${queryString ? `?${queryString}` : ''}`, transform: (data: DailyReportSummaryApi) => ({ date: data.date, dayOfWeek: data.day_of_week, noteReceivableTotal: data.note_receivable_total, foreignCurrencyTotal: data.foreign_currency_total, cashAssetTotal: data.cash_asset_total, krwTotals: data.krw_totals, usdTotals: data.usd_totals, }), errorMessage: '요약 조회에 실패했습니다.', }); } // ===== 일일 보고서 엑셀 다운로드 ===== export async function exportDailyReportExcel(params?: { date?: string; }): Promise<{ success: boolean; data?: Blob; filename?: string; error?: string; }> { try { const cookieStore = await cookies(); const token = cookieStore.get('access_token')?.value; const headers: HeadersInit = { 'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'Authorization': token ? `Bearer ${token}` : '', 'X-API-KEY': process.env.API_KEY || '', }; const searchParams = new URLSearchParams(); if (params?.date) searchParams.set('date', params.date); const queryString = searchParams.toString(); const response = await fetch( `${API_URL}/api/v1/daily-report/export${queryString ? `?${queryString}` : ''}`, { method: 'GET', headers } ); if (!response.ok) { return { success: false, error: `API 오류: ${response.status}` }; } const blob = await response.blob(); const contentDisposition = response.headers.get('Content-Disposition'); const filename = contentDisposition?.match(/filename="?(.+)"?/)?.[1] || `일일일보_${params?.date || 'today'}.xlsx`; return { success: true, data: blob, filename }; } catch (error) { if (isNextRedirectError(error)) throw error; console.error('[DailyReportActions] exportDailyReportExcel error:', error); return { success: false, error: '서버 오류가 발생했습니다.' }; } }