diff options
| author | joonhoekim <26rote@gmail.com> | 2025-09-02 08:36:03 +0000 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-09-02 08:36:03 +0000 |
| commit | 659c46ed04758584b79a8f97074d3213bb7e252e (patch) | |
| tree | 9e7000873fbdc78df52fbbaac4c6d52f484255cb /lib/vendor-basic-info/basic-info-client.tsx | |
| parent | f72142f6cc46c7be5bf90803d365c2ecd144c53d (diff) | |
(김준회) 벤더기본정보 - 매출정보 처리 (수동입력은 구현하지 않았음)
Diffstat (limited to 'lib/vendor-basic-info/basic-info-client.tsx')
| -rw-r--r-- | lib/vendor-basic-info/basic-info-client.tsx | 198 |
1 files changed, 148 insertions, 50 deletions
diff --git a/lib/vendor-basic-info/basic-info-client.tsx b/lib/vendor-basic-info/basic-info-client.tsx index ce8e4dfc..82133f28 100644 --- a/lib/vendor-basic-info/basic-info-client.tsx +++ b/lib/vendor-basic-info/basic-info-client.tsx @@ -27,6 +27,7 @@ import { AdditionalInfoDialog } from "@/components/vendor-regular-registrations/ import { getSiteVisitRequestsByVendorId } from "@/lib/site-visit/service"; import { fetchVendorRegistrationStatus } from "@/lib/vendor-regular-registrations/service"; import { getVendorAttachmentsByType, getVendorPeriodicGrade, getVendorTypeInfo } from "@/lib/vendor-info/service"; +import { useCreditIntegration } from "./use-credit-integration"; // downloadFile은 동적으로 import import { Table, @@ -327,6 +328,20 @@ export default function BasicInfoClient({ const [editMode, setEditMode] = useState(false); const [isPending, startTransition] = useTransition(); + // 신용평가사 데이터 통합 훅 + const { + loading: creditLoading, + error: creditError, + creditResults, + selectedCreditService, + bestResult, + getCurrentResult, + handleCreditServiceChange, + transformCreditToSalesData, + creditServices, + reload: reloadCreditData + } = useCreditIntegration(vendorId); + // 다이얼로그 상태 const [pqDialogOpen, setPqDialogOpen] = useState(false); const [siteVisitDialogOpen, setSiteVisitDialogOpen] = useState(false); @@ -1178,6 +1193,71 @@ export default function BasicInfoClient({ subtitle="(3개년)" noPadding={true} content={ + <div className="space-y-4"> + {/* 신용평가사 선택 */} + <div className="p-4 border-b bg-muted/30"> + <div className="flex items-center justify-between mb-2"> + <span className="text-sm font-medium">신용평가사 데이터</span> + {creditLoading && ( + <div className="flex items-center gap-2 text-sm text-muted-foreground"> + <div className="animate-spin h-4 w-4 border-2 border-primary border-t-transparent rounded-full"></div> + 로딩 중... + </div> + )} + </div> + + <div className="flex items-center gap-4"> + <Select + value={selectedCreditService} + onValueChange={handleCreditServiceChange} + > + <SelectTrigger className="w-48"> + <SelectValue placeholder="신용평가사 선택" /> + </SelectTrigger> + <SelectContent> + {creditServices.map((service) => { + const result = creditResults.find(r => r.code === service.code); + return ( + <SelectItem key={service.code} value={service.code}> + {service.name} + {service.code !== 'auto' && result && ( + <span className="ml-2 text-xs text-muted-foreground"> + {result.success + ? `(${result.dataCount}개 항목)` + : '(조회 실패)' + } + </span> + )} + </SelectItem> + ); + })} + </SelectContent> + </Select> + + {getCurrentResult() && ( + <div className="text-sm text-muted-foreground"> + 선택됨: <span className="font-medium">{getCurrentResult()?.name}</span> + {selectedCreditService === 'auto' && bestResult && ( + <span className="ml-1">({bestResult.dataCount}개 항목으로 자동선택)</span> + )} + </div> + )} + + {creditError && ( + <div className="text-sm text-destructive"> + {creditError} + </div> + )} + + {!creditLoading && !creditError && creditResults.length > 0 && !getCurrentResult()?.data && ( + <div className="text-sm text-muted-foreground"> + 신용평가 데이터가 없습니다 + </div> + )} + </div> + </div> + + {/* 테이블 */} <Table> <TableHeader> <TableRow> @@ -1263,59 +1343,77 @@ export default function BasicInfoClient({ </TableRow> </TableHeader> <TableBody> - {["20231231", "20221231", "20211231"].map((dateKey) => { - const year = dateKey; - const salesData = initialData.salesInfo?.[year]; - const metricsData = initialData.calculatedMetrics?.[dateKey]; + {(() => { + // 신용평가사 데이터 우선 사용, 없으면 기존 데이터 사용 + const currentResult = getCurrentResult(); + const creditTransformedData = currentResult?.data ? transformCreditToSalesData(currentResult.data) : null; + + const salesData = creditTransformedData?.salesInfo || initialData.salesInfo || {}; + const metricsData = creditTransformedData?.calculatedMetrics || initialData.calculatedMetrics || {}; + + // 실제 데이터에서 연도 추출 (고정 연도 사용하지 않음) + const years = Object.keys(salesData).sort().reverse().slice(0, 3); + + // 데이터가 없는 경우 기본 연도 사용 + if (years.length === 0 && !getCurrentResult()?.data) { + years.push("20231231", "20221231", "20211231"); + } + + return years.map((dateKey) => { + const formattedDate = dateKey; // YYYYMMDD 형식으로 표시 + const yearSalesData = salesData[dateKey]; + const yearMetricsData = metricsData[dateKey]; - return ( - <TableRow key={dateKey}> - <TableCell className="text-center font-medium border-r bg-yellow-50"> - {year} - </TableCell> - <TableCell className="text-right border-r"> - {salesData - ? ( - parseInt(salesData.totalDebt.replace(/,/g, "")) + - parseInt(salesData.totalEquity.replace(/,/g, "")) - ).toLocaleString() - : "-"} - </TableCell> - <TableCell className="text-right border-r"> - {salesData?.totalDebt || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {salesData?.totalEquity || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {salesData?.operatingProfit || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {salesData?.netIncome || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {metricsData?.debtRatio?.toFixed(1) || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {metricsData?.borrowingDependency?.toFixed(1) || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {metricsData?.operatingMargin?.toFixed(1) || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {metricsData?.netMargin?.toFixed(1) || "-"} - </TableCell> - <TableCell className="text-right border-r"> - {metricsData?.salesGrowth?.toFixed(1) || "-"} - </TableCell> - <TableCell className="text-right"> - {metricsData?.currentRatio?.toFixed(1) || "-"} - </TableCell> - </TableRow> - ); - })} + return ( + <TableRow key={dateKey}> + <TableCell className="text-center font-medium border-r bg-yellow-50"> + {formattedDate} + </TableCell> + <TableCell className="text-right border-r"> + {yearSalesData && yearSalesData.totalDebt && yearSalesData.totalEquity + ? ( + parseInt(yearSalesData.totalDebt.replace(/,/g, "")) + + parseInt(yearSalesData.totalEquity.replace(/,/g, "")) + ).toLocaleString() + : "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearSalesData?.totalDebt || "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearSalesData?.totalEquity || "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearSalesData?.operatingProfit || "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearSalesData?.netIncome || "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearMetricsData?.debtRatio ? yearMetricsData.debtRatio.toFixed(1) : "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearMetricsData?.borrowingDependency ? yearMetricsData.borrowingDependency.toFixed(1) : "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearMetricsData?.operatingMargin ? yearMetricsData.operatingMargin.toFixed(1) : "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearMetricsData?.netMargin ? yearMetricsData.netMargin.toFixed(1) : "-"} + </TableCell> + <TableCell className="text-right border-r"> + {yearMetricsData?.salesGrowth ? yearMetricsData.salesGrowth.toFixed(1) : "-"} + </TableCell> + <TableCell className="text-right"> + {yearMetricsData?.currentRatio ? yearMetricsData.currentRatio.toFixed(1) : "-"} + </TableCell> + </TableRow> + ); + }); + })()} </TableBody> </Table> + </div> } /> |
