summaryrefslogtreecommitdiff
path: root/lib/tech-vendors/table/vendor-all-export.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tech-vendors/table/vendor-all-export.ts')
-rw-r--r--lib/tech-vendors/table/vendor-all-export.ts512
1 files changed, 256 insertions, 256 deletions
diff --git a/lib/tech-vendors/table/vendor-all-export.ts b/lib/tech-vendors/table/vendor-all-export.ts
index f2650102..f1492324 100644
--- a/lib/tech-vendors/table/vendor-all-export.ts
+++ b/lib/tech-vendors/table/vendor-all-export.ts
@@ -1,257 +1,257 @@
-// /lib/vendor-export.ts
-import ExcelJS from "exceljs"
-import { TechVendor, TechVendorContact, TechVendorItem } from "@/db/schema/techVendors"
-import { exportTechVendorDetails } from "../service";
-
-/**
- * 선택된 벤더의 모든 관련 정보를 통합 시트 형식으로 엑셀로 내보내는 함수
- * - 기본정보 시트
- * - 연락처 시트
- * - 아이템 시트
- * 각 시트에는 식별을 위한 벤더 코드, 벤더명, 세금ID가 포함됨
- */
-export async function exportVendorsWithRelatedData(
- vendors: TechVendor[],
- filename = "tech-vendors-detailed"
-): Promise<void> {
- if (!vendors.length) return;
-
- // 선택된 벤더 ID 목록
- const vendorIds = vendors.map(vendor => vendor.id);
-
- try {
- // 서버로부터 모든 관련 데이터 가져오기
- const vendorsWithDetails = await exportTechVendorDetails(vendorIds);
-
- if (!vendorsWithDetails.length) {
- throw new Error("내보내기 데이터를 가져오는 중 오류가 발생했습니다.");
- }
-
- // 워크북 생성
- const workbook = new ExcelJS.Workbook();
-
- // 데이터 타입 확인 (서비스에서 반환하는 실제 데이터 형태)
- const vendorData = vendorsWithDetails as unknown as any[];
-
- // ===== 1. 기본 정보 시트 =====
- createBasicInfoSheet(workbook, vendorData);
-
- // ===== 2. 연락처 시트 =====
- createContactsSheet(workbook, vendorData);
-
- // ===== 3. 아이템 시트 =====
- createItemsSheet(workbook, vendorData);
-
-
- // 파일 다운로드
- const buffer = await workbook.xlsx.writeBuffer();
- const blob = new Blob([buffer], {
- type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
- });
- const url = URL.createObjectURL(blob);
- const link = document.createElement("a");
- link.href = url;
- link.download = `${filename}-${new Date().toISOString().split("T")[0]}.xlsx`;
- link.click();
- URL.revokeObjectURL(url);
-
- return;
- } catch (error) {
- console.error("Export error:", error);
- throw error;
- }
-}
-
-// 기본 정보 시트 생성 함수
-function createBasicInfoSheet(
- workbook: ExcelJS.Workbook,
- vendors: TechVendor[]
-): void {
- const basicInfoSheet = workbook.addWorksheet("기본정보");
-
- // 기본 정보 시트 헤더 설정
- basicInfoSheet.columns = [
- { header: "업체코드", key: "vendorCode", width: 15 },
- { header: "업체명", key: "vendorName", width: 20 },
- { header: "세금ID", key: "taxId", width: 15 },
- { header: "국가", key: "country", width: 10 },
- { header: "상태", key: "status", width: 15 },
- { header: "이메일", key: "email", width: 20 },
- { header: "전화번호", key: "phone", width: 15 },
- { header: "웹사이트", key: "website", width: 20 },
- { header: "주소", key: "address", width: 30 },
- { header: "대표자명", key: "representativeName", width: 15 },
- { header: "생성일", key: "createdAt", width: 15 },
- { header: "벤더타입", key: "techVendorType", width: 15 },
- { header: "대리점명", key: "agentName", width: 15 },
- { header: "대리점연락처", key: "agentPhone", width: 15 },
- { header: "대리점이메일", key: "agentEmail", width: 25 },
- { header: "대리점주소", key: "agentAddress", width: 30 },
- { header: "대리점국가", key: "agentCountry", width: 15 },
- { header: "대리점영문국가명", key: "agentCountryEng", width: 20 },
- ];
-
- // 헤더 스타일 설정
- applyHeaderStyle(basicInfoSheet);
-
- // 벤더 데이터 추가
- vendors.forEach((vendor: TechVendor) => {
- basicInfoSheet.addRow({
- vendorCode: vendor.vendorCode || "",
- vendorName: vendor.vendorName,
- taxId: vendor.taxId,
- country: vendor.country,
- status: getStatusText(vendor.status), // 상태 코드를 읽기 쉬운 텍스트로 변환
- email: vendor.email,
- phone: vendor.phone,
- website: vendor.website,
- address: vendor.address,
- representativeName: vendor.representativeName,
- createdAt: vendor.createdAt ? formatDate(vendor.createdAt) : "",
- techVendorType: vendor.techVendorType?.split(',').join(', ') || vendor.techVendorType,
- });
- });
-}
-
-// 연락처 시트 생성 함수
-function createContactsSheet(
- workbook: ExcelJS.Workbook,
- vendors: TechVendor[]
-): void {
- const contactsSheet = workbook.addWorksheet("연락처");
-
- contactsSheet.columns = [
- // 벤더 식별 정보
- { header: "업체코드", key: "vendorCode", width: 15 },
- { header: "업체명", key: "vendorName", width: 20 },
- { header: "세금ID", key: "taxId", width: 15 },
- // 연락처 정보
- { header: "이름", key: "contactName", width: 15 },
- { header: "직책", key: "contactPosition", width: 15 },
- { header: "이메일", key: "contactEmail", width: 25 },
- { header: "전화번호", key: "contactPhone", width: 15 },
- { header: "주요 연락처", key: "isPrimary", width: 10 },
- ];
-
- // 헤더 스타일 설정
- applyHeaderStyle(contactsSheet);
-
- // 벤더별 연락처 데이터 추가
- vendors.forEach((vendor: TechVendor) => {
- if (vendor.contacts && vendor.contacts.length > 0) {
- vendor.contacts.forEach((contact: TechVendorContact) => {
- contactsSheet.addRow({
- // 벤더 식별 정보
- vendorCode: vendor.vendorCode || "",
- vendorName: vendor.vendorName,
- taxId: vendor.taxId,
- // 연락처 정보
- contactName: contact.contactName,
- contactPosition: contact.contactPosition || "",
- contactEmail: contact.contactEmail,
- contactPhone: contact.contactPhone || "",
- isPrimary: contact.isPrimary ? "예" : "아니오",
- });
- });
- } else {
- // 연락처가 없는 경우에도 벤더 정보만 추가
- contactsSheet.addRow({
- vendorCode: vendor.vendorCode || "",
- vendorName: vendor.vendorName,
- taxId: vendor.taxId,
- contactName: "",
- contactPosition: "",
- contactEmail: "",
- contactPhone: "",
- isPrimary: "",
- });
- }
- });
-}
-
-// 아이템 시트 생성 함수
-function createItemsSheet(
- workbook: ExcelJS.Workbook,
- vendors: TechVendor[]
-): void {
- const itemsSheet = workbook.addWorksheet("아이템");
-
- itemsSheet.columns = [
- // 벤더 식별 정보
- { header: "업체코드", key: "vendorCode", width: 15 },
- { header: "업체명", key: "vendorName", width: 20 },
- { header: "세금ID", key: "taxId", width: 15 },
- // 아이템 정보
- { header: "아이템 코드", key: "itemCode", width: 15 },
- { header: "아이템명", key: "itemName", width: 25 },
- { header: "설명", key: "description", width: 30 },
- { header: "등록일", key: "createdAt", width: 15 },
- ];
-
- // 헤더 스타일 설정
- applyHeaderStyle(itemsSheet);
-
- // 벤더별 아이템 데이터 추가
- vendors.forEach((vendor: TechVendor) => {
- if (vendor.items && vendor.items.length > 0) {
- vendor.items.forEach((item: TechVendorItem) => {
- itemsSheet.addRow({
- // 벤더 식별 정보
- vendorCode: vendor.vendorCode || "",
- vendorName: vendor.vendorName,
- taxId: vendor.taxId,
- // 아이템 정보
- itemCode: item.itemCode,
- itemName: item.itemName,
- createdAt: item.createdAt ? formatDate(item.createdAt) : "",
- });
- });
- } else {
- // 아이템이 없는 경우에도 벤더 정보만 추가
- itemsSheet.addRow({
- vendorCode: vendor.vendorCode || "",
- vendorName: vendor.vendorName,
- taxId: vendor.taxId,
- itemCode: "",
- itemName: "",
- createdAt: "",
- });
- }
- });
-}
-
-
-// 헤더 스타일 적용 함수
-function applyHeaderStyle(sheet: ExcelJS.Worksheet): void {
- const headerRow = sheet.getRow(1);
- headerRow.font = { bold: true };
- headerRow.alignment = { horizontal: "center" };
- headerRow.eachCell((cell: ExcelJS.Cell) => {
- cell.fill = {
- type: "pattern",
- pattern: "solid",
- fgColor: { argb: "FFCCCCCC" },
- };
- });
-}
-
-// 날짜 포맷 함수
-function formatDate(date: Date | string): string {
- if (!date) return "";
- if (typeof date === 'string') {
- date = new Date(date);
- }
- return date.toISOString().split('T')[0];
-}
-
-
-// 상태 코드를 읽기 쉬운 텍스트로 변환하는 함수
-function getStatusText(status: string): string {
- const statusMap: Record<string, string> = {
- "ACTIVE": "활성",
- "INACTIVE": "비활성",
- "BLACKLISTED": "거래 금지"
- };
-
- return statusMap[status] || status;
+// /lib/vendor-export.ts
+import ExcelJS from "exceljs"
+import { TechVendor, TechVendorContact, TechVendorItem } from "@/db/schema/techVendors"
+import { exportTechVendorDetails } from "../service";
+
+/**
+ * 선택된 벤더의 모든 관련 정보를 통합 시트 형식으로 엑셀로 내보내는 함수
+ * - 기본정보 시트
+ * - 연락처 시트
+ * - 아이템 시트
+ * 각 시트에는 식별을 위한 벤더 코드, 벤더명, 세금ID가 포함됨
+ */
+export async function exportVendorsWithRelatedData(
+ vendors: TechVendor[],
+ filename = "tech-vendors-detailed"
+): Promise<void> {
+ if (!vendors.length) return;
+
+ // 선택된 벤더 ID 목록
+ const vendorIds = vendors.map(vendor => vendor.id);
+
+ try {
+ // 서버로부터 모든 관련 데이터 가져오기
+ const vendorsWithDetails = await exportTechVendorDetails(vendorIds);
+
+ if (!vendorsWithDetails.length) {
+ throw new Error("내보내기 데이터를 가져오는 중 오류가 발생했습니다.");
+ }
+
+ // 워크북 생성
+ const workbook = new ExcelJS.Workbook();
+
+ // 데이터 타입 확인 (서비스에서 반환하는 실제 데이터 형태)
+ const vendorData = vendorsWithDetails as unknown as any[];
+
+ // ===== 1. 기본 정보 시트 =====
+ createBasicInfoSheet(workbook, vendorData);
+
+ // ===== 2. 연락처 시트 =====
+ createContactsSheet(workbook, vendorData);
+
+ // ===== 3. 아이템 시트 =====
+ createItemsSheet(workbook, vendorData);
+
+
+ // 파일 다운로드
+ const buffer = await workbook.xlsx.writeBuffer();
+ const blob = new Blob([buffer], {
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ });
+ const url = URL.createObjectURL(blob);
+ const link = document.createElement("a");
+ link.href = url;
+ link.download = `${filename}-${new Date().toISOString().split("T")[0]}.xlsx`;
+ link.click();
+ URL.revokeObjectURL(url);
+
+ return;
+ } catch (error) {
+ console.error("Export error:", error);
+ throw error;
+ }
+}
+
+// 기본 정보 시트 생성 함수
+function createBasicInfoSheet(
+ workbook: ExcelJS.Workbook,
+ vendors: TechVendor[]
+): void {
+ const basicInfoSheet = workbook.addWorksheet("기본정보");
+
+ // 기본 정보 시트 헤더 설정
+ basicInfoSheet.columns = [
+ { header: "업체코드", key: "vendorCode", width: 15 },
+ { header: "업체명", key: "vendorName", width: 20 },
+ { header: "세금ID", key: "taxId", width: 15 },
+ { header: "국가", key: "country", width: 10 },
+ { header: "상태", key: "status", width: 15 },
+ { header: "이메일", key: "email", width: 20 },
+ { header: "전화번호", key: "phone", width: 15 },
+ { header: "웹사이트", key: "website", width: 20 },
+ { header: "주소", key: "address", width: 30 },
+ { header: "대표자명", key: "representativeName", width: 15 },
+ { header: "생성일", key: "createdAt", width: 15 },
+ { header: "벤더타입", key: "techVendorType", width: 15 },
+ { header: "에이전트명", key: "agentName", width: 15 },
+ { header: "에이전트연락처", key: "agentPhone", width: 15 },
+ { header: "에이전트이메일", key: "agentEmail", width: 25 },
+ { header: "에이전트주소", key: "agentAddress", width: 30 },
+ { header: "에이전트국가", key: "agentCountry", width: 15 },
+ { header: "에이전트영문국가명", key: "agentCountryEng", width: 20 },
+ ];
+
+ // 헤더 스타일 설정
+ applyHeaderStyle(basicInfoSheet);
+
+ // 벤더 데이터 추가
+ vendors.forEach((vendor: TechVendor) => {
+ basicInfoSheet.addRow({
+ vendorCode: vendor.vendorCode || "",
+ vendorName: vendor.vendorName,
+ taxId: vendor.taxId,
+ country: vendor.country,
+ status: getStatusText(vendor.status), // 상태 코드를 읽기 쉬운 텍스트로 변환
+ email: vendor.email,
+ phone: vendor.phone,
+ website: vendor.website,
+ address: vendor.address,
+ representativeName: vendor.representativeName,
+ createdAt: vendor.createdAt ? formatDate(vendor.createdAt) : "",
+ techVendorType: vendor.techVendorType?.split(',').join(', ') || vendor.techVendorType,
+ });
+ });
+}
+
+// 연락처 시트 생성 함수
+function createContactsSheet(
+ workbook: ExcelJS.Workbook,
+ vendors: TechVendor[]
+): void {
+ const contactsSheet = workbook.addWorksheet("연락처");
+
+ contactsSheet.columns = [
+ // 벤더 식별 정보
+ { header: "업체코드", key: "vendorCode", width: 15 },
+ { header: "업체명", key: "vendorName", width: 20 },
+ { header: "세금ID", key: "taxId", width: 15 },
+ // 연락처 정보
+ { header: "이름", key: "contactName", width: 15 },
+ { header: "직책", key: "contactPosition", width: 15 },
+ { header: "이메일", key: "contactEmail", width: 25 },
+ { header: "전화번호", key: "contactPhone", width: 15 },
+ { header: "주요 연락처", key: "isPrimary", width: 10 },
+ ];
+
+ // 헤더 스타일 설정
+ applyHeaderStyle(contactsSheet);
+
+ // 벤더별 연락처 데이터 추가
+ vendors.forEach((vendor: TechVendor) => {
+ if (vendor.contacts && vendor.contacts.length > 0) {
+ vendor.contacts.forEach((contact: TechVendorContact) => {
+ contactsSheet.addRow({
+ // 벤더 식별 정보
+ vendorCode: vendor.vendorCode || "",
+ vendorName: vendor.vendorName,
+ taxId: vendor.taxId,
+ // 연락처 정보
+ contactName: contact.contactName,
+ contactPosition: contact.contactPosition || "",
+ contactEmail: contact.contactEmail,
+ contactPhone: contact.contactPhone || "",
+ isPrimary: contact.isPrimary ? "예" : "아니오",
+ });
+ });
+ } else {
+ // 연락처가 없는 경우에도 벤더 정보만 추가
+ contactsSheet.addRow({
+ vendorCode: vendor.vendorCode || "",
+ vendorName: vendor.vendorName,
+ taxId: vendor.taxId,
+ contactName: "",
+ contactPosition: "",
+ contactEmail: "",
+ contactPhone: "",
+ isPrimary: "",
+ });
+ }
+ });
+}
+
+// 아이템 시트 생성 함수
+function createItemsSheet(
+ workbook: ExcelJS.Workbook,
+ vendors: TechVendor[]
+): void {
+ const itemsSheet = workbook.addWorksheet("아이템");
+
+ itemsSheet.columns = [
+ // 벤더 식별 정보
+ { header: "업체코드", key: "vendorCode", width: 15 },
+ { header: "업체명", key: "vendorName", width: 20 },
+ { header: "세금ID", key: "taxId", width: 15 },
+ // 아이템 정보
+ { header: "아이템 코드", key: "itemCode", width: 15 },
+ { header: "아이템명", key: "itemName", width: 25 },
+ { header: "설명", key: "description", width: 30 },
+ { header: "등록일", key: "createdAt", width: 15 },
+ ];
+
+ // 헤더 스타일 설정
+ applyHeaderStyle(itemsSheet);
+
+ // 벤더별 아이템 데이터 추가
+ vendors.forEach((vendor: TechVendor) => {
+ if (vendor.items && vendor.items.length > 0) {
+ vendor.items.forEach((item: TechVendorItem) => {
+ itemsSheet.addRow({
+ // 벤더 식별 정보
+ vendorCode: vendor.vendorCode || "",
+ vendorName: vendor.vendorName,
+ taxId: vendor.taxId,
+ // 아이템 정보
+ itemCode: item.itemCode,
+ itemName: item.itemName,
+ createdAt: item.createdAt ? formatDate(item.createdAt) : "",
+ });
+ });
+ } else {
+ // 아이템이 없는 경우에도 벤더 정보만 추가
+ itemsSheet.addRow({
+ vendorCode: vendor.vendorCode || "",
+ vendorName: vendor.vendorName,
+ taxId: vendor.taxId,
+ itemCode: "",
+ itemName: "",
+ createdAt: "",
+ });
+ }
+ });
+}
+
+
+// 헤더 스타일 적용 함수
+function applyHeaderStyle(sheet: ExcelJS.Worksheet): void {
+ const headerRow = sheet.getRow(1);
+ headerRow.font = { bold: true };
+ headerRow.alignment = { horizontal: "center" };
+ headerRow.eachCell((cell: ExcelJS.Cell) => {
+ cell.fill = {
+ type: "pattern",
+ pattern: "solid",
+ fgColor: { argb: "FFCCCCCC" },
+ };
+ });
+}
+
+// 날짜 포맷 함수
+function formatDate(date: Date | string): string {
+ if (!date) return "";
+ if (typeof date === 'string') {
+ date = new Date(date);
+ }
+ return date.toISOString().split('T')[0];
+}
+
+
+// 상태 코드를 읽기 쉬운 텍스트로 변환하는 함수
+function getStatusText(status: string): string {
+ const statusMap: Record<string, string> = {
+ "ACTIVE": "활성",
+ "INACTIVE": "비활성",
+ "BLACKLISTED": "거래 금지"
+ };
+
+ return statusMap[status] || status;
} \ No newline at end of file