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: 계정과목 통합 계획/분석/체크리스트, 대시보드 검증 문서 추가
This commit is contained in:
유병철
2026-03-08 12:44:36 +09:00
parent 74e0e2bf44
commit 7d369d1404
53 changed files with 3690 additions and 496 deletions

View File

@@ -42,8 +42,9 @@ import {
TableRow,
TableFooter,
} from '@/components/ui/table';
import { createManualJournal, getAccountSubjects, getVendorList } from './actions';
import type { JournalEntryRow, JournalSide, AccountSubject, VendorOption } from './types';
import { AccountSubjectSelect } from '@/components/accounting/common';
import { createManualJournal, getVendorList } from './actions';
import type { JournalEntryRow, JournalSide, VendorOption } from './types';
import { JOURNAL_SIDE_OPTIONS } from './types';
import { getTodayString } from '@/lib/utils/date';
@@ -81,7 +82,6 @@ export function ManualJournalEntryModal({
const [rows, setRows] = useState<JournalEntryRow[]>([createEmptyRow()]);
// 옵션 데이터
const [accountSubjects, setAccountSubjects] = useState<AccountSubject[]>([]);
const [vendors, setVendors] = useState<VendorOption[]>([]);
const [isSubmitting, setIsSubmitting] = useState(false);
@@ -94,13 +94,7 @@ export function ManualJournalEntryModal({
setDescription('');
setRows([createEmptyRow()]);
Promise.all([
getAccountSubjects({ category: 'all' }),
getVendorList(),
]).then(([subjectsRes, vendorsRes]) => {
if (subjectsRes.success && subjectsRes.data) {
setAccountSubjects(subjectsRes.data.filter((s) => s.isActive));
}
getVendorList().then((vendorsRes) => {
if (vendorsRes.success && vendorsRes.data) {
setVendors(vendorsRes.data);
}
@@ -272,24 +266,14 @@ export function ManualJournalEntryModal({
</div>
</TableCell>
<TableCell className="p-1">
<Select
value={row.accountSubjectId || 'none'}
<AccountSubjectSelect
value={row.accountSubjectId}
onValueChange={(v) =>
handleRowChange(row.id, 'accountSubjectId', v === 'none' ? '' : v)
handleRowChange(row.id, 'accountSubjectId', v)
}
>
<SelectTrigger className="h-8 text-sm">
<SelectValue placeholder="선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="none"></SelectItem>
{accountSubjects.map((s) => (
<SelectItem key={s.id} value={s.id}>
{s.name}
</SelectItem>
))}
</SelectContent>
</Select>
size="sm"
placeholder="선택"
/>
</TableCell>
<TableCell className="p-1">
<Select