Files
sam-react-prod/src/components/accounting/TaxInvoiceManagement/actions.ts
유병철 7d369d1404 feat: 계정과목 공통화 및 회계 모듈 전반 개선
- 계정과목 관리를 accounting/common/으로 통합 (AccountSubjectSettingModal 이동)
- GeneralJournalEntry: 계정과목 actions/types 분리, 모달 import 경로 변경
- CardTransactionInquiry: JournalEntryModal/ManualInputModal 개선
- TaxInvoiceManagement: actions/types 리팩토링
- DepositManagement/WithdrawalManagement: 소폭 개선
- ExpectedExpenseManagement: UI 개선
- GiftCertificateManagement: 상세/목록 개선
- BillManagement: BillDetail/Client/index 소폭 추가
- PurchaseManagement/SalesManagement: 상세뷰 개선
- CEO 대시보드: dashboard-invalidation 유틸 추가, useCEODashboard 확장
- OrderRegistration/OrderSalesDetailView 소폭 수정
- claudedocs: 계정과목 통합 계획/분석/체크리스트, 대시보드 검증 문서 추가
2026-03-08 12:44:36 +09:00

160 lines
4.8 KiB
TypeScript

'use server';
import { executeServerAction, type ActionResult } from '@/lib/api/execute-server-action';
import { executePaginatedAction } from '@/lib/api/execute-paginated-action';
import { buildApiUrl } from '@/lib/api/query-params';
import type {
TaxInvoiceMgmtRecord,
TaxInvoiceMgmtApiData,
TaxInvoiceSummary,
TaxInvoiceSummaryApiData,
CardHistoryApiData,
CardHistoryRecord,
ManualEntryFormData,
JournalEntryRow,
} from './types';
import {
transformApiToFrontend,
transformFrontendToApi,
transformCardHistoryApi,
transformSummaryApi,
} from './types';
// ===== 세금계산서 목록 조회 =====
export async function getTaxInvoices(params: {
division?: string;
dateType?: string;
startDate?: string;
endDate?: string;
vendorSearch?: string;
page?: number;
perPage?: number;
}) {
// frontend 'purchase' → backend 'purchases'
const direction = params.division === 'purchase' ? 'purchases' : params.division;
return executePaginatedAction<TaxInvoiceMgmtApiData, TaxInvoiceMgmtRecord>({
url: buildApiUrl('/api/v1/tax-invoices', {
direction,
issue_date_from: params.startDate,
issue_date_to: params.endDate,
corp_name: params.vendorSearch || undefined,
page: params.page,
per_page: params.perPage,
}),
transform: transformApiToFrontend,
errorMessage: '세금계산서 목록 조회에 실패했습니다.',
});
}
// ===== 세금계산서 요약 조회 =====
export async function getTaxInvoiceSummary(params: {
dateType?: string;
startDate?: string;
endDate?: string;
vendorSearch?: string;
}): Promise<ActionResult<TaxInvoiceSummary>> {
return executeServerAction<TaxInvoiceSummaryApiData, TaxInvoiceSummary>({
url: buildApiUrl('/api/v1/tax-invoices/summary', {
issue_date_from: params.startDate,
issue_date_to: params.endDate,
corp_name: params.vendorSearch || undefined,
}),
transform: transformSummaryApi,
errorMessage: '세금계산서 요약 조회에 실패했습니다.',
});
}
// ===== 세금계산서 수기 등록 =====
export async function createTaxInvoice(
data: ManualEntryFormData
): Promise<ActionResult<TaxInvoiceMgmtRecord>> {
return executeServerAction({
url: buildApiUrl('/api/v1/tax-invoices'),
method: 'POST',
body: transformFrontendToApi(data),
transform: (d: TaxInvoiceMgmtApiData) => transformApiToFrontend(d),
errorMessage: '세금계산서 등록에 실패했습니다.',
});
}
// ===== 카드 내역 조회 =====
export async function getCardHistory(params: {
startDate?: string;
endDate?: string;
search?: string;
page?: number;
perPage?: number;
}) {
return executePaginatedAction<CardHistoryApiData, CardHistoryRecord>({
url: buildApiUrl('/api/v1/card-transactions', {
start_date: params.startDate,
end_date: params.endDate,
search: params.search || undefined,
page: params.page,
per_page: params.perPage,
}),
transform: transformCardHistoryApi,
errorMessage: '카드 내역 조회에 실패했습니다.',
});
}
// ===== 분개 내역 조회 =====
export async function getJournalEntries(invoiceId: string): Promise<ActionResult<{
rows: { id: string; side: string; account_subject: string; debit_amount: number; credit_amount: number }[];
}>> {
return executeServerAction({
url: buildApiUrl(`/api/v1/tax-invoices/${invoiceId}/journal-entries`),
errorMessage: '분개 내역 조회에 실패했습니다.',
});
}
// ===== 분개 수정 =====
export async function updateJournalEntry(
invoiceId: string,
rows: JournalEntryRow[]
): Promise<ActionResult> {
return executeServerAction({
url: buildApiUrl(`/api/v1/tax-invoices/${invoiceId}/journal-entries`),
method: 'PUT',
body: {
rows: rows.map((r) => ({
side: r.side,
account_subject: r.accountSubject,
debit_amount: r.debitAmount,
credit_amount: r.creditAmount,
})),
},
errorMessage: '분개 수정에 실패했습니다.',
});
}
// ===== 분개 삭제 =====
export async function deleteJournalEntry(invoiceId: string): Promise<ActionResult> {
return executeServerAction({
url: buildApiUrl(`/api/v1/tax-invoices/${invoiceId}/journal-entries`),
method: 'DELETE',
errorMessage: '분개 삭제에 실패했습니다.',
});
}
// ===== 엑셀 다운로드 =====
export async function downloadTaxInvoiceExcel(params: {
division?: string;
dateType?: string;
startDate?: string;
endDate?: string;
vendorSearch?: string;
}): Promise<ActionResult<{ url: string }>> {
return executeServerAction({
url: buildApiUrl('/api/v1/tax-invoices/export', {
division: params.division,
date_type: params.dateType,
start_date: params.startDate,
end_date: params.endDate,
vendor_search: params.vendorSearch || undefined,
}),
errorMessage: '엑셀 다운로드에 실패했습니다.',
});
}