fix: [misc] 거래처 카운트 수정 + 생산현황판 통계 API 교체
- 거래처 목록 카운트를 stats API 호출로 교체 - 생산현황판 대시보드 통계를 work-orders/stats API 활용
This commit is contained in:
@@ -94,22 +94,17 @@ export default function CustomerAccountManagementPage() {
|
||||
// 전체 통계 로드 (최초 1회만)
|
||||
const loadTotalStats = useCallback(async () => {
|
||||
try {
|
||||
// 전체 데이터 조회 (검색 조건 없이)
|
||||
const response = await fetch("/api/proxy/clients?size=1000");
|
||||
const response = await fetch("/api/proxy/clients/stats");
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
if (result.success && result.data) {
|
||||
const allClients = result.data.data || [];
|
||||
const data = result.data;
|
||||
setTotalStats({
|
||||
total: result.data.total || allClients.length,
|
||||
purchase: allClients.filter((c: { client_type?: string }) =>
|
||||
c.client_type === "매입" || c.client_type === "매입매출"
|
||||
).length,
|
||||
sales: allClients.filter((c: { client_type?: string }) =>
|
||||
c.client_type === "매출" || c.client_type === "매입매출"
|
||||
).length,
|
||||
active: allClients.filter((c: { is_active?: boolean }) => c.is_active === true).length,
|
||||
inactive: allClients.filter((c: { is_active?: boolean }) => c.is_active === false).length,
|
||||
total: data.total ?? 0,
|
||||
purchase: (data.purchase ?? 0) + (data.both ?? 0),
|
||||
sales: (data.sales ?? 0) + (data.both ?? 0),
|
||||
active: data.active ?? 0,
|
||||
inactive: data.inactive ?? 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,18 @@ export async function getProcessOptions(): Promise<{
|
||||
};
|
||||
}
|
||||
|
||||
// ===== 작업지시 통계 조회 (백엔드 stats API) =====
|
||||
interface WorkOrderStatsApi {
|
||||
total: number;
|
||||
unassigned: number;
|
||||
pending: number;
|
||||
waiting: number;
|
||||
in_progress: number;
|
||||
completed: number;
|
||||
shipped: number;
|
||||
by_process: Record<string, number>;
|
||||
}
|
||||
|
||||
// ===== 대시보드 데이터 조회 =====
|
||||
export async function getDashboardData(processCode?: string): Promise<{
|
||||
success: boolean;
|
||||
@@ -128,30 +140,49 @@ export async function getDashboardData(processCode?: string): Promise<{
|
||||
stats: { total: 0, waiting: 0, inProgress: 0, completed: 0, urgent: 0, delayed: 0 },
|
||||
};
|
||||
|
||||
const result = await executeServerAction<{ data: WorkOrderApiItem[] }>({
|
||||
url: buildApiUrl('/api/v1/work-orders', {
|
||||
per_page: 100,
|
||||
process_code: processCode && processCode !== 'all' ? processCode : undefined,
|
||||
// 통계와 목록을 병렬 조회
|
||||
const [statsResult, listResult] = await Promise.all([
|
||||
executeServerAction<WorkOrderStatsApi>({
|
||||
url: buildApiUrl('/api/v1/work-orders/stats'),
|
||||
errorMessage: '통계 조회에 실패했습니다.',
|
||||
}),
|
||||
errorMessage: '데이터 조회에 실패했습니다.',
|
||||
});
|
||||
executeServerAction<{ data: WorkOrderApiItem[] }>({
|
||||
url: buildApiUrl('/api/v1/work-orders', {
|
||||
per_page: 100,
|
||||
process_code: processCode && processCode !== 'all' ? processCode : undefined,
|
||||
}),
|
||||
errorMessage: '데이터 조회에 실패했습니다.',
|
||||
}),
|
||||
]);
|
||||
|
||||
if (!result.success || !result.data) {
|
||||
return { ...emptyResult, error: result.error };
|
||||
if (!listResult.success || !listResult.data) {
|
||||
return { ...emptyResult, error: listResult.error };
|
||||
}
|
||||
|
||||
const apiData = result.data.data || [];
|
||||
const apiData = listResult.data.data || [];
|
||||
const workOrders = apiData.map(transformToProductionFormat);
|
||||
|
||||
// 통계 계산
|
||||
const stats: DashboardStats = {
|
||||
total: workOrders.length,
|
||||
waiting: workOrders.filter(o => o.status === 'waiting').length,
|
||||
inProgress: workOrders.filter(o => o.status === 'inProgress').length,
|
||||
completed: workOrders.filter(o => o.status === 'completed').length,
|
||||
urgent: workOrders.filter(o => o.isUrgent).length,
|
||||
delayed: workOrders.filter(o => o.isDelayed).length,
|
||||
};
|
||||
// 통계: 백엔드 stats API 기반 (정확한 전체 카운트)
|
||||
// urgent/delayed는 목록 데이터에서 계산 (stats API에 미포함)
|
||||
const apiStats = statsResult.success && statsResult.data ? statsResult.data : null;
|
||||
const stats: DashboardStats = apiStats
|
||||
? {
|
||||
total: apiStats.total,
|
||||
waiting: (apiStats.unassigned ?? 0) + (apiStats.pending ?? 0) + (apiStats.waiting ?? 0),
|
||||
inProgress: apiStats.in_progress ?? 0,
|
||||
completed: (apiStats.completed ?? 0) + (apiStats.shipped ?? 0),
|
||||
urgent: workOrders.filter(o => o.isUrgent).length,
|
||||
delayed: workOrders.filter(o => o.isDelayed).length,
|
||||
}
|
||||
: {
|
||||
// stats API 실패 시 목록 데이터 기반 폴백
|
||||
total: workOrders.length,
|
||||
waiting: workOrders.filter(o => o.status === 'waiting').length,
|
||||
inProgress: workOrders.filter(o => o.status === 'inProgress').length,
|
||||
completed: workOrders.filter(o => o.status === 'completed').length,
|
||||
urgent: workOrders.filter(o => o.isUrgent).length,
|
||||
delayed: workOrders.filter(o => o.isDelayed).length,
|
||||
};
|
||||
|
||||
// 작업자별 현황 집계
|
||||
const workerMap = new Map<string, WorkerStatus>();
|
||||
|
||||
Reference in New Issue
Block a user