fix(WEB): 기타 버그 수정 및 개선
- CardTransactionInquiry: account_code 'unset' 처리 개선 - WorkOrderCreate: DevFill 공정 옵션 로딩 타이밍 수정 - accountingData: 생성기 개선 - api/errors: 에러 처리 개선
This commit is contained in:
@@ -296,7 +296,7 @@ export async function createCardTransaction(data: {
|
|||||||
merchant_name: data.merchantName,
|
merchant_name: data.merchantName,
|
||||||
amount: data.amount,
|
amount: data.amount,
|
||||||
description: data.memo,
|
description: data.memo,
|
||||||
account_code: data.usageType,
|
account_code: data.usageType === 'unset' ? null : data.usageType,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ export async function updateCardTransaction(
|
|||||||
merchant_name: data.merchantName,
|
merchant_name: data.merchantName,
|
||||||
amount: data.amount,
|
amount: data.amount,
|
||||||
description: data.memo,
|
description: data.memo,
|
||||||
account_code: data.usageType,
|
account_code: data.usageType === 'unset' ? null : data.usageType,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -164,6 +164,19 @@ export interface Vendor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== API 응답 타입 =====
|
// ===== API 응답 타입 =====
|
||||||
|
export interface SaleApiOrderItem {
|
||||||
|
id: number;
|
||||||
|
order_id: number;
|
||||||
|
item_name: string;
|
||||||
|
quantity: string | number;
|
||||||
|
unit_price: string | number;
|
||||||
|
supply_amount: string | number;
|
||||||
|
tax_amount: string | number;
|
||||||
|
total_amount: string | number;
|
||||||
|
note: string | null;
|
||||||
|
sort_order: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SaleApiData {
|
export interface SaleApiData {
|
||||||
id: number;
|
id: number;
|
||||||
sale_number: string;
|
sale_number: string;
|
||||||
@@ -173,6 +186,10 @@ export interface SaleApiData {
|
|||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
order?: {
|
||||||
|
id: number;
|
||||||
|
items?: SaleApiOrderItem[];
|
||||||
|
};
|
||||||
supply_amount: string | number;
|
supply_amount: string | number;
|
||||||
tax_amount: string | number;
|
tax_amount: string | number;
|
||||||
total_amount: string | number;
|
total_amount: string | number;
|
||||||
@@ -197,6 +214,17 @@ export const API_STATUS_MAP: Record<string, SalesStatus> = {
|
|||||||
|
|
||||||
// API 응답 → 프론트엔드 타입 변환
|
// API 응답 → 프론트엔드 타입 변환
|
||||||
export function transformApiToFrontend(apiData: SaleApiData): SalesRecord {
|
export function transformApiToFrontend(apiData: SaleApiData): SalesRecord {
|
||||||
|
// 수주(Order)의 품목(items)을 매출 품목으로 변환
|
||||||
|
const items: SalesItem[] = (apiData.order?.items ?? []).map((item, index) => ({
|
||||||
|
id: String(item.id),
|
||||||
|
itemName: item.item_name ?? '',
|
||||||
|
quantity: parseFloat(String(item.quantity)) || 0,
|
||||||
|
unitPrice: parseFloat(String(item.unit_price)) || 0,
|
||||||
|
supplyAmount: parseFloat(String(item.supply_amount)) || 0,
|
||||||
|
vat: parseFloat(String(item.tax_amount)) || 0,
|
||||||
|
note: item.note ?? '',
|
||||||
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: String(apiData.id),
|
id: String(apiData.id),
|
||||||
salesNo: apiData.sale_number,
|
salesNo: apiData.sale_number,
|
||||||
@@ -205,7 +233,7 @@ export function transformApiToFrontend(apiData: SaleApiData): SalesRecord {
|
|||||||
vendorName: apiData.client?.name ?? '',
|
vendorName: apiData.client?.name ?? '',
|
||||||
salesType: 'other', // API에 없음, 기본값
|
salesType: 'other', // API에 없음, 기본값
|
||||||
accountSubject: 'other', // API에 없음, 기본값
|
accountSubject: 'other', // API에 없음, 기본값
|
||||||
items: [], // API에 없음, 빈 배열
|
items, // 수주 품목에서 가져옴
|
||||||
totalSupplyAmount: parseFloat(String(apiData.supply_amount)) || 0,
|
totalSupplyAmount: parseFloat(String(apiData.supply_amount)) || 0,
|
||||||
totalVat: parseFloat(String(apiData.tax_amount)) || 0,
|
totalVat: parseFloat(String(apiData.tax_amount)) || 0,
|
||||||
totalAmount: parseFloat(String(apiData.total_amount)) || 0,
|
totalAmount: parseFloat(String(apiData.total_amount)) || 0,
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ const DEPOSIT_NOTES = [
|
|||||||
|
|
||||||
export interface DepositFormData {
|
export interface DepositFormData {
|
||||||
depositDate: string;
|
depositDate: string;
|
||||||
accountName: string;
|
bankAccountId: string;
|
||||||
depositorName: string;
|
depositorName: string;
|
||||||
depositAmount: number;
|
depositAmount: number;
|
||||||
note: string;
|
note: string;
|
||||||
@@ -70,15 +70,17 @@ export interface DepositFormData {
|
|||||||
|
|
||||||
export interface GenerateDepositDataOptions {
|
export interface GenerateDepositDataOptions {
|
||||||
vendors?: Array<{ id: string; name: string }>;
|
vendors?: Array<{ id: string; name: string }>;
|
||||||
|
bankAccounts?: Array<{ id: string; name: string }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateDepositData(options: GenerateDepositDataOptions = {}): DepositFormData {
|
export function generateDepositData(options: GenerateDepositDataOptions = {}): DepositFormData {
|
||||||
const { vendors = SAMPLE_VENDORS } = options;
|
const { vendors = SAMPLE_VENDORS, bankAccounts = [] } = options;
|
||||||
const vendor = randomPick(vendors);
|
const vendor = randomPick(vendors);
|
||||||
|
const bankAccount = bankAccounts.length > 0 ? randomPick(bankAccounts) : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
depositDate: today(),
|
depositDate: today(),
|
||||||
accountName: randomPick(ACCOUNT_NAMES),
|
bankAccountId: bankAccount?.id || '',
|
||||||
depositorName: randomPick(DEPOSITOR_NAMES),
|
depositorName: randomPick(DEPOSITOR_NAMES),
|
||||||
depositAmount: randomInt(100000, 10000000),
|
depositAmount: randomInt(100000, 10000000),
|
||||||
note: randomPick(DEPOSIT_NOTES),
|
note: randomPick(DEPOSIT_NOTES),
|
||||||
@@ -119,7 +121,7 @@ const WITHDRAWAL_NOTES = [
|
|||||||
|
|
||||||
export interface WithdrawalFormData {
|
export interface WithdrawalFormData {
|
||||||
withdrawalDate: string;
|
withdrawalDate: string;
|
||||||
accountName: string;
|
bankAccountId: string;
|
||||||
recipientName: string;
|
recipientName: string;
|
||||||
withdrawalAmount: number;
|
withdrawalAmount: number;
|
||||||
note: string;
|
note: string;
|
||||||
@@ -129,15 +131,17 @@ export interface WithdrawalFormData {
|
|||||||
|
|
||||||
export interface GenerateWithdrawalDataOptions {
|
export interface GenerateWithdrawalDataOptions {
|
||||||
vendors?: Array<{ id: string; name: string }>;
|
vendors?: Array<{ id: string; name: string }>;
|
||||||
|
bankAccounts?: Array<{ id: string; name: string }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateWithdrawalData(options: GenerateWithdrawalDataOptions = {}): WithdrawalFormData {
|
export function generateWithdrawalData(options: GenerateWithdrawalDataOptions = {}): WithdrawalFormData {
|
||||||
const { vendors = SAMPLE_VENDORS } = options;
|
const { vendors = SAMPLE_VENDORS, bankAccounts = [] } = options;
|
||||||
const vendor = randomPick(vendors);
|
const vendor = randomPick(vendors);
|
||||||
|
const bankAccount = bankAccounts.length > 0 ? randomPick(bankAccounts) : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
withdrawalDate: today(),
|
withdrawalDate: today(),
|
||||||
accountName: randomPick(ACCOUNT_NAMES),
|
bankAccountId: bankAccount?.id || '',
|
||||||
recipientName: randomPick(RECIPIENT_NAMES),
|
recipientName: randomPick(RECIPIENT_NAMES),
|
||||||
withdrawalAmount: randomInt(50000, 5000000),
|
withdrawalAmount: randomInt(50000, 5000000),
|
||||||
note: randomPick(WITHDRAWAL_NOTES),
|
note: randomPick(WITHDRAWAL_NOTES),
|
||||||
@@ -264,6 +268,7 @@ export function generatePurchaseApprovalData(options: GeneratePurchaseApprovalDa
|
|||||||
approvalLine: [currentUser],
|
approvalLine: [currentUser],
|
||||||
references: [randomReference],
|
references: [randomReference],
|
||||||
proposalData: {
|
proposalData: {
|
||||||
|
vendorId: vendor.id,
|
||||||
vendor: vendor.name,
|
vendor: vendor.name,
|
||||||
vendorPaymentDate: today(),
|
vendorPaymentDate: today(),
|
||||||
title: randomPick(PROPOSAL_TITLES),
|
title: randomPick(PROPOSAL_TITLES),
|
||||||
|
|||||||
@@ -119,8 +119,12 @@ export function WorkOrderCreate() {
|
|||||||
// DevToolbar 자동 채우기
|
// DevToolbar 자동 채우기
|
||||||
useDevFill(
|
useDevFill(
|
||||||
'workOrder',
|
'workOrder',
|
||||||
useCallback(() => {
|
useCallback(async () => {
|
||||||
const sampleData = generateWorkOrderData({ processOptions });
|
// 공정 옵션 직접 가져오기 (state가 아직 로딩 전일 수 있음)
|
||||||
|
const processResult = await getProcessOptions();
|
||||||
|
const processes = processResult.success ? processResult.data : [];
|
||||||
|
|
||||||
|
const sampleData = generateWorkOrderData({ processOptions: processes });
|
||||||
|
|
||||||
// 수동 등록 모드로 변경
|
// 수동 등록 모드로 변경
|
||||||
setMode('manual');
|
setMode('manual');
|
||||||
@@ -139,7 +143,7 @@ export function WorkOrderCreate() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
toast.success('[Dev] 작업지시 폼이 자동으로 채워졌습니다.');
|
toast.success('[Dev] 작업지시 폼이 자동으로 채워졌습니다.');
|
||||||
}, [processOptions])
|
}, [])
|
||||||
);
|
);
|
||||||
|
|
||||||
// 수주 선택 핸들러
|
// 수주 선택 핸들러
|
||||||
|
|||||||
@@ -48,13 +48,14 @@ export function createAuthErrorResponse(message?: string): ApiErrorResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 일반 API 에러 응답 생성 헬퍼
|
* 일반 API 에러 응답 생성 헬퍼
|
||||||
|
* - 디버깅을 위해 상태 코드를 메시지에 포함
|
||||||
*/
|
*/
|
||||||
export function createErrorResponse(status: number, message: string, code?: string): ApiErrorResponse {
|
export function createErrorResponse(status: number, message: string, code?: string): ApiErrorResponse {
|
||||||
return {
|
return {
|
||||||
__error: true,
|
__error: true,
|
||||||
__authError: status === 401,
|
__authError: status === 401,
|
||||||
status,
|
status,
|
||||||
message,
|
message: `[${status}] ${message}`,
|
||||||
code,
|
code,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user