- AccountSubjectSelect 공통 컴포넌트 신규 (계정과목 선택 통합) - 일반전표 수동입력/수정 모달 계정과목 연동 - 세금계산서 관리 타입 시스템 재정의 + 전표 연동 모달 - 어음관리 리팩토링 + 상품권 접대비 연동 - 카드거래 조회 전표 연동 모달 개선 - 악성채권/입출금/매입매출/거래처 상세 뷰 보강
164 lines
4.6 KiB
TypeScript
164 lines
4.6 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 {
|
|
GeneralJournalRecord,
|
|
GeneralJournalApiData,
|
|
GeneralJournalSummary,
|
|
GeneralJournalSummaryApiData,
|
|
JournalEntryRow,
|
|
VendorOption,
|
|
} from './types';
|
|
import {
|
|
transformApiToFrontend,
|
|
transformSummaryApi,
|
|
} from './types';
|
|
|
|
// ===== 전표 목록 조회 =====
|
|
export async function getJournalEntries(params: {
|
|
startDate?: string;
|
|
endDate?: string;
|
|
search?: string;
|
|
page?: number;
|
|
perPage?: number;
|
|
}) {
|
|
const result = await executePaginatedAction<GeneralJournalApiData, GeneralJournalRecord>({
|
|
url: buildApiUrl('/api/v1/general-journal-entries', {
|
|
start_date: params.startDate,
|
|
end_date: params.endDate,
|
|
search: params.search || undefined,
|
|
page: params.page,
|
|
per_page: params.perPage,
|
|
}),
|
|
transform: transformApiToFrontend,
|
|
errorMessage: '전표 목록 조회에 실패했습니다.',
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
// ===== 전표 요약 통계 조회 =====
|
|
export async function getJournalSummary(params: {
|
|
startDate?: string;
|
|
endDate?: string;
|
|
search?: string;
|
|
}): Promise<ActionResult<GeneralJournalSummary>> {
|
|
const result = await executeServerAction({
|
|
url: buildApiUrl('/api/v1/general-journal-entries/summary', {
|
|
start_date: params.startDate,
|
|
end_date: params.endDate,
|
|
search: params.search || undefined,
|
|
}),
|
|
transform: (data: GeneralJournalSummaryApiData) => transformSummaryApi(data),
|
|
errorMessage: '전표 요약 조회에 실패했습니다.',
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
// ===== 수기 전표 등록 =====
|
|
export async function createManualJournal(data: {
|
|
journalDate: string;
|
|
description: string;
|
|
rows: JournalEntryRow[];
|
|
}): Promise<ActionResult> {
|
|
return executeServerAction({
|
|
url: buildApiUrl('/api/v1/general-journal-entries'),
|
|
method: 'POST',
|
|
body: {
|
|
journal_date: data.journalDate,
|
|
description: data.description,
|
|
rows: data.rows.map((r) => ({
|
|
side: r.side,
|
|
account_subject_id: r.accountSubjectId,
|
|
vendor_id: r.vendorId || null,
|
|
debit_amount: r.debitAmount,
|
|
credit_amount: r.creditAmount,
|
|
memo: r.memo || null,
|
|
})),
|
|
},
|
|
errorMessage: '수기 전표 등록에 실패했습니다.',
|
|
});
|
|
}
|
|
|
|
// ===== 분개 상세 조회 =====
|
|
type JournalDetailData = {
|
|
id: number;
|
|
date: string;
|
|
division: string;
|
|
amount: number;
|
|
description: string;
|
|
bank_name: string;
|
|
account_number: string;
|
|
journal_memo: string;
|
|
rows: {
|
|
id: number;
|
|
side: string;
|
|
account_subject_id: number;
|
|
account_subject_name: string;
|
|
vendor_id: number | null;
|
|
vendor_name: string;
|
|
debit_amount: number;
|
|
credit_amount: number;
|
|
memo: string;
|
|
}[];
|
|
};
|
|
|
|
export async function getJournalDetail(id: string): Promise<ActionResult<JournalDetailData>> {
|
|
const result = await executeServerAction<JournalDetailData>({
|
|
url: buildApiUrl(`/api/v1/general-journal-entries/${id}`),
|
|
errorMessage: '분개 상세 조회에 실패했습니다.',
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
// ===== 분개 수정 =====
|
|
export async function updateJournalDetail(
|
|
id: string,
|
|
data: {
|
|
journalMemo: string;
|
|
rows: JournalEntryRow[];
|
|
}
|
|
): Promise<ActionResult> {
|
|
return executeServerAction({
|
|
url: buildApiUrl(`/api/v1/general-journal-entries/${id}/journal`),
|
|
method: 'PUT',
|
|
body: {
|
|
journal_memo: data.journalMemo,
|
|
rows: data.rows.map((r) => ({
|
|
side: r.side,
|
|
account_subject_id: r.accountSubjectId,
|
|
vendor_id: r.vendorId || null,
|
|
debit_amount: r.debitAmount,
|
|
credit_amount: r.creditAmount,
|
|
memo: r.memo || null,
|
|
})),
|
|
},
|
|
errorMessage: '분개 수정에 실패했습니다.',
|
|
});
|
|
}
|
|
|
|
// ===== 분개 삭제 =====
|
|
export async function deleteJournalDetail(id: string): Promise<ActionResult> {
|
|
return executeServerAction({
|
|
url: buildApiUrl(`/api/v1/general-journal-entries/${id}/journal`),
|
|
method: 'DELETE',
|
|
errorMessage: '분개 삭제에 실패했습니다.',
|
|
});
|
|
}
|
|
|
|
// ===== 거래처 목록 조회 =====
|
|
export async function getVendorList(): Promise<ActionResult<VendorOption[]>> {
|
|
const result = await executeServerAction({
|
|
url: buildApiUrl('/api/v1/vendors', { per_page: 9999 }),
|
|
transform: (data: { id: number; name: string }[]) =>
|
|
data.map((v) => ({ id: String(v.id), name: v.name })),
|
|
errorMessage: '거래처 목록 조회에 실패했습니다.',
|
|
});
|
|
|
|
return result;
|
|
}
|