- CardTransactionInquiry: account_code 'unset' 처리 개선 - WorkOrderCreate: DevFill 공정 옵션 로딩 타이밍 수정 - accountingData: 생성기 개선 - api/errors: 에러 처리 개선
347 lines
9.3 KiB
TypeScript
347 lines
9.3 KiB
TypeScript
/**
|
|
* 회계 샘플 데이터 생성기 (입금, 출금, 매입, 카드)
|
|
*/
|
|
|
|
import {
|
|
randomPick,
|
|
randomInt,
|
|
today,
|
|
randomRemark,
|
|
} from './index';
|
|
|
|
// ===== 공통 상수 =====
|
|
|
|
// 거래처 목록 (실제로는 API에서 가져옴)
|
|
const SAMPLE_VENDORS = [
|
|
{ id: '1', name: '(주)삼성전자' },
|
|
{ id: '2', name: '(주)LG화학' },
|
|
{ id: '3', name: '현대중공업' },
|
|
{ id: '4', name: '(주)포스코' },
|
|
{ id: '5', name: '한화솔루션' },
|
|
];
|
|
|
|
// 계좌명 목록
|
|
const ACCOUNT_NAMES = [
|
|
'기업은행 1234-5678-9012',
|
|
'국민은행 111-22-33333',
|
|
'신한은행 110-123-456789',
|
|
'우리은행 1002-123-456789',
|
|
'하나은행 888-123456-78901',
|
|
];
|
|
|
|
// ===== 입금 관련 =====
|
|
|
|
// 입금 유형
|
|
const DEPOSIT_TYPES = ['revenue', 'deposit', 'sales', 'other', 'unset'];
|
|
|
|
// 입금자명
|
|
const DEPOSITOR_NAMES = [
|
|
'홍길동',
|
|
'김철수',
|
|
'이영희',
|
|
'박민수',
|
|
'최지영',
|
|
'(주)삼성전자',
|
|
'(주)LG화학',
|
|
'현대중공업',
|
|
];
|
|
|
|
// 입금 적요
|
|
const DEPOSIT_NOTES = [
|
|
'제품 판매대금',
|
|
'선수금 입금',
|
|
'용역비 입금',
|
|
'대금 회수',
|
|
'계약금 입금',
|
|
'잔금 입금',
|
|
'기타 입금',
|
|
'',
|
|
];
|
|
|
|
export interface DepositFormData {
|
|
depositDate: string;
|
|
bankAccountId: string;
|
|
depositorName: string;
|
|
depositAmount: number;
|
|
note: string;
|
|
vendorId: string;
|
|
depositType: string;
|
|
}
|
|
|
|
export interface GenerateDepositDataOptions {
|
|
vendors?: Array<{ id: string; name: string }>;
|
|
bankAccounts?: Array<{ id: string; name: string }>;
|
|
}
|
|
|
|
export function generateDepositData(options: GenerateDepositDataOptions = {}): DepositFormData {
|
|
const { vendors = SAMPLE_VENDORS, bankAccounts = [] } = options;
|
|
const vendor = randomPick(vendors);
|
|
const bankAccount = bankAccounts.length > 0 ? randomPick(bankAccounts) : null;
|
|
|
|
return {
|
|
depositDate: today(),
|
|
bankAccountId: bankAccount?.id || '',
|
|
depositorName: randomPick(DEPOSITOR_NAMES),
|
|
depositAmount: randomInt(100000, 10000000),
|
|
note: randomPick(DEPOSIT_NOTES),
|
|
vendorId: vendor.id,
|
|
depositType: 'unset', // 미설정으로 고정
|
|
};
|
|
}
|
|
|
|
// ===== 출금 관련 =====
|
|
|
|
// 출금 유형
|
|
const WITHDRAWAL_TYPES = ['expense', 'payment', 'purchase', 'salary', 'other', 'unset'];
|
|
|
|
// 수취인명
|
|
const RECIPIENT_NAMES = [
|
|
'(주)삼성전자',
|
|
'(주)LG화학',
|
|
'현대중공업',
|
|
'(주)포스코',
|
|
'한화솔루션',
|
|
'홍길동',
|
|
'김철수',
|
|
'국세청',
|
|
];
|
|
|
|
// 출금 적요
|
|
const WITHDRAWAL_NOTES = [
|
|
'자재 구매대금',
|
|
'외주 가공비',
|
|
'임대료 지급',
|
|
'전기요금',
|
|
'수도요금',
|
|
'통신비',
|
|
'급여 지급',
|
|
'세금 납부',
|
|
'',
|
|
];
|
|
|
|
export interface WithdrawalFormData {
|
|
withdrawalDate: string;
|
|
bankAccountId: string;
|
|
recipientName: string;
|
|
withdrawalAmount: number;
|
|
note: string;
|
|
vendorId: string;
|
|
withdrawalType: string;
|
|
}
|
|
|
|
export interface GenerateWithdrawalDataOptions {
|
|
vendors?: Array<{ id: string; name: string }>;
|
|
bankAccounts?: Array<{ id: string; name: string }>;
|
|
}
|
|
|
|
export function generateWithdrawalData(options: GenerateWithdrawalDataOptions = {}): WithdrawalFormData {
|
|
const { vendors = SAMPLE_VENDORS, bankAccounts = [] } = options;
|
|
const vendor = randomPick(vendors);
|
|
const bankAccount = bankAccounts.length > 0 ? randomPick(bankAccounts) : null;
|
|
|
|
return {
|
|
withdrawalDate: today(),
|
|
bankAccountId: bankAccount?.id || '',
|
|
recipientName: randomPick(RECIPIENT_NAMES),
|
|
withdrawalAmount: randomInt(50000, 5000000),
|
|
note: randomPick(WITHDRAWAL_NOTES),
|
|
vendorId: vendor.id,
|
|
withdrawalType: 'unset', // 미설정으로 고정
|
|
};
|
|
}
|
|
|
|
// ===== 매입(지출결의서) 관련 =====
|
|
|
|
// 문서 유형
|
|
const DOCUMENT_TYPES = ['proposal', 'expenseReport', 'expenseEstimate'];
|
|
|
|
// 지출결의서 제목
|
|
const PROPOSAL_TITLES = [
|
|
'사무용품 구매 요청',
|
|
'장비 수리비 지출 요청',
|
|
'출장비 정산 요청',
|
|
'회의비 지출 요청',
|
|
'교육비 지출 요청',
|
|
'소프트웨어 라이선스 구매',
|
|
'마케팅 비용 지출 요청',
|
|
'복리후생비 지출 요청',
|
|
];
|
|
|
|
// 지출결의서 내용
|
|
const PROPOSAL_DESCRIPTIONS = [
|
|
'업무 효율 향상을 위한 사무용품 구매가 필요합니다.',
|
|
'노후화된 장비의 수리가 필요하여 지출을 요청드립니다.',
|
|
'고객 미팅을 위한 출장 경비를 정산해주시기 바랍니다.',
|
|
'팀 회의 진행을 위한 다과 비용입니다.',
|
|
'직원 역량 강화를 위한 교육비 지출입니다.',
|
|
'업무용 소프트웨어 라이선스 갱신 비용입니다.',
|
|
'신규 고객 유치를 위한 마케팅 활동 비용입니다.',
|
|
'직원 복지 증진을 위한 지출입니다.',
|
|
];
|
|
|
|
// 지출 사유
|
|
const PROPOSAL_REASONS = [
|
|
'업무 효율성 향상',
|
|
'고객 서비스 개선',
|
|
'비용 절감 효과',
|
|
'법적 의무 이행',
|
|
'안전 관리 필수',
|
|
'계약 조건 이행',
|
|
'직원 역량 강화',
|
|
'시설 유지보수',
|
|
];
|
|
|
|
// 결재자/참조자 타입
|
|
export interface ApprovalPerson {
|
|
id: string;
|
|
department: string;
|
|
position: string;
|
|
name: string;
|
|
}
|
|
|
|
// 경리/회계/재무 부서 샘플 직원 (참조용)
|
|
const ACCOUNTING_STAFF: ApprovalPerson[] = [
|
|
{ id: 'acc-1', department: '경리팀', position: '대리', name: '김경리' },
|
|
{ id: 'acc-2', department: '경리팀', position: '사원', name: '박경리' },
|
|
{ id: 'acc-3', department: '회계팀', position: '과장', name: '이회계' },
|
|
{ id: 'acc-4', department: '회계팀', position: '대리', name: '최회계' },
|
|
{ id: 'acc-5', department: '재무팀', position: '차장', name: '정재무' },
|
|
{ id: 'acc-6', department: '재무팀', position: '과장', name: '강재무' },
|
|
];
|
|
|
|
export interface PurchaseApprovalFormData {
|
|
basicInfo: {
|
|
drafter: string;
|
|
draftDate: string;
|
|
documentNo: string;
|
|
documentType: string;
|
|
};
|
|
approvalLine: ApprovalPerson[];
|
|
references: ApprovalPerson[];
|
|
proposalData: {
|
|
vendor: string;
|
|
vendorPaymentDate: string;
|
|
title: string;
|
|
description: string;
|
|
reason: string;
|
|
estimatedCost: number;
|
|
};
|
|
}
|
|
|
|
export interface GeneratePurchaseApprovalDataOptions {
|
|
vendors?: Array<{ id: string; name: string }>;
|
|
documentType?: string;
|
|
currentUser?: ApprovalPerson;
|
|
}
|
|
|
|
// 문서번호 생성 (YYYYMMDD-HHMMSS-XXX 형식)
|
|
function generateDocumentNo(): string {
|
|
const now = new Date();
|
|
const date = now.toISOString().slice(0, 10).replace(/-/g, '');
|
|
const time = now.toTimeString().slice(0, 8).replace(/:/g, '');
|
|
const random = String(randomInt(100, 999));
|
|
return `DEV-${date}-${time.slice(0, 4)}-${random}`;
|
|
}
|
|
|
|
export function generatePurchaseApprovalData(options: GeneratePurchaseApprovalDataOptions = {}): PurchaseApprovalFormData {
|
|
const { vendors = SAMPLE_VENDORS, documentType = 'proposal' } = options;
|
|
const vendor = randomPick(vendors);
|
|
|
|
// 현재 사용자를 결재선에 추가 (기본값: 홍길동)
|
|
const currentUser: ApprovalPerson = options.currentUser || {
|
|
id: 'user-1',
|
|
department: '개발팀',
|
|
position: '사원',
|
|
name: '홍길동',
|
|
};
|
|
|
|
// 경리/회계/재무 직원 중 랜덤으로 1명 참조 추가
|
|
const randomReference = randomPick(ACCOUNTING_STAFF);
|
|
|
|
return {
|
|
basicInfo: {
|
|
drafter: currentUser.name,
|
|
draftDate: new Date().toISOString().slice(0, 16).replace('T', ' '),
|
|
documentNo: generateDocumentNo(),
|
|
documentType,
|
|
},
|
|
approvalLine: [currentUser],
|
|
references: [randomReference],
|
|
proposalData: {
|
|
vendorId: vendor.id,
|
|
vendor: vendor.name,
|
|
vendorPaymentDate: today(),
|
|
title: randomPick(PROPOSAL_TITLES),
|
|
description: randomPick(PROPOSAL_DESCRIPTIONS),
|
|
reason: randomPick(PROPOSAL_REASONS),
|
|
estimatedCost: randomInt(100000, 5000000),
|
|
},
|
|
};
|
|
}
|
|
|
|
// ===== 카드 거래 관련 =====
|
|
|
|
// 가맹점명 목록
|
|
const MERCHANT_NAMES = [
|
|
'스타벅스 강남점',
|
|
'GS25 역삼점',
|
|
'이마트 성수점',
|
|
'쿠팡 결제',
|
|
'네이버페이',
|
|
'배달의민족',
|
|
'카카오택시',
|
|
'주유소(SK에너지)',
|
|
'올리브영 신촌점',
|
|
'다이소 홍대점',
|
|
'맥도날드 종로점',
|
|
'교보문고 광화문점',
|
|
];
|
|
|
|
// 카드 적요 목록
|
|
const CARD_MEMOS = [
|
|
'업무용 점심식대',
|
|
'사무용품 구매',
|
|
'출장 교통비',
|
|
'고객 접대비',
|
|
'회의 다과비',
|
|
'업무 차량 주유',
|
|
'직원 간식 구매',
|
|
'택배비',
|
|
'',
|
|
];
|
|
|
|
// 사용유형 (usageType) - 카드 결제 분류
|
|
const CARD_USAGE_TYPES = ['unset', 'meal', 'transport', 'supplies', 'entertainment', 'other'];
|
|
|
|
export interface CardTransactionFormData {
|
|
cardId: string;
|
|
usedAt: string;
|
|
merchantName: string;
|
|
amount: number;
|
|
memo: string;
|
|
usageType: string;
|
|
}
|
|
|
|
export interface GenerateCardTransactionDataOptions {
|
|
cards?: Array<{ id: string | number; name: string; cardNumber?: string }>;
|
|
}
|
|
|
|
// datetime-local 형식으로 현재 시간 반환 (YYYY-MM-DDTHH:mm)
|
|
function nowDateTimeLocal(): string {
|
|
const now = new Date();
|
|
return now.toISOString().slice(0, 16);
|
|
}
|
|
|
|
export function generateCardTransactionData(options: GenerateCardTransactionDataOptions = {}): CardTransactionFormData {
|
|
const { cards } = options;
|
|
const card = cards && cards.length > 0 ? randomPick(cards) : null;
|
|
|
|
return {
|
|
cardId: card ? String(card.id) : '',
|
|
usedAt: nowDateTimeLocal(),
|
|
merchantName: randomPick(MERCHANT_NAMES),
|
|
amount: randomInt(5000, 500000),
|
|
memo: randomPick(CARD_MEMOS),
|
|
usageType: 'unset', // 미설정으로 고정
|
|
};
|
|
} |