summaryrefslogtreecommitdiff
path: root/lib/tech-vendor-possible-items/table/excel-template.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tech-vendor-possible-items/table/excel-template.tsx')
-rw-r--r--lib/tech-vendor-possible-items/table/excel-template.tsx151
1 files changed, 119 insertions, 32 deletions
diff --git a/lib/tech-vendor-possible-items/table/excel-template.tsx b/lib/tech-vendor-possible-items/table/excel-template.tsx
index 70a7eddf..20880350 100644
--- a/lib/tech-vendor-possible-items/table/excel-template.tsx
+++ b/lib/tech-vendor-possible-items/table/excel-template.tsx
@@ -2,7 +2,7 @@ import * as ExcelJS from 'exceljs';
import { saveAs } from "file-saver";
/**
- * 기술영업 벤더 가능 아이템 Import를 위한 Excel 템플릿 파일 생성 및 다운로드
+ * 기술영업 벤더 가능 아이템 Import를 위한 Excel 템플릿 파일 생성 및 다운로드 (새로운 스키마 버전)
*/
export async function exportTechVendorPossibleItemsTemplate() {
// 워크북 생성
@@ -13,11 +13,15 @@ export async function exportTechVendorPossibleItemsTemplate() {
// 워크시트 생성
const worksheet = workbook.addWorksheet('기술영업 벤더 가능 아이템');
- // 컬럼 헤더 정의 및 스타일 적용
+ // 컬럼 헤더 정의 및 스타일 적용 (새로운 스키마에 맞춰)
worksheet.columns = [
- { header: '아이템코드', key: 'itemCode', width: 20 },
- { header: '벤더코드', key: 'vendorCode', width: 15 },
- { header: '벤더이메일', key: 'vendorEmail', width: 30 },
+ { header: '벤더이메일 (필수)', key: 'vendorEmail', width: 30 },
+ { header: '아이템코드 (필수)', key: 'itemCode', width: 20 },
+ { header: '공종 (선택)', key: 'workType', width: 15 },
+ { header: '선종 (선택)', key: 'shipTypes', width: 20 },
+ { header: '아이템리스트 (선택)', key: 'itemList', width: 35 },
+ { header: '서브아이템리스트 (선택)', key: 'subItemList', width: 35 },
+ { header: '벤더코드 (호환성)', key: 'vendorCode', width: 15 },
];
// 헤더 스타일 적용
@@ -44,18 +48,58 @@ export async function exportTechVendorPossibleItemsTemplate() {
};
});
- // 샘플 데이터 추가
+ // 샘플 데이터 추가 (새로운 스키마에 맞춰)
const sampleData = [
- { itemCode: 'ITEM001', vendorCode: 'V001', vendorEmail: '' },
- { itemCode: 'ITEM001', vendorCode: 'V002', vendorEmail: '' },
- { itemCode: 'ITEM002', vendorCode: '', vendorEmail: 'vendor@example.com' },
- { itemCode: 'ITEM002', vendorCode: 'V002', vendorEmail: '' },
- { itemCode: 'ITEM004', vendorCode: '', vendorEmail: 'vendor2@example.com' },
+ {
+ vendorEmail: 'vendor1@example.com',
+ itemCode: 'ITEM001',
+ workType: '용접',
+ shipTypes: '컨테이너선',
+ itemList: '선체 용접 작업',
+ subItemList: '외판 용접, 내부 구조 용접',
+ vendorCode: 'V001'
+ },
+ {
+ vendorEmail: 'vendor2@example.com',
+ itemCode: 'ITEM002',
+ workType: '도장',
+ shipTypes: '벌크선',
+ itemList: '선체 도장 작업',
+ subItemList: '프라이머, 탑코트',
+ vendorCode: ''
+ },
+ {
+ vendorEmail: 'vendor3@example.com',
+ itemCode: 'ITEM003',
+ workType: '기계',
+ shipTypes: '탱커',
+ itemList: '기계 설비 설치',
+ subItemList: '엔진, 펌프, 배관',
+ vendorCode: ''
+ },
+ {
+ vendorEmail: 'vendor1@example.com',
+ itemCode: 'ITEM004',
+ workType: '용접',
+ shipTypes: '컨테이너선, 벌크선',
+ itemList: '특수 용접 작업',
+ subItemList: '',
+ vendorCode: 'V001'
+ },
+ {
+ vendorEmail: 'vendor4@example.com',
+ itemCode: 'ITEM005',
+ workType: '',
+ shipTypes: '',
+ itemList: '',
+ subItemList: '',
+ vendorCode: 'V004'
+ },
];
sampleData.forEach((data) => {
const row = worksheet.addRow(data);
- row.eachCell((cell) => {
+ row.eachCell((cell, colNumber) => {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
@@ -66,35 +110,75 @@ export async function exportTechVendorPossibleItemsTemplate() {
vertical: 'middle',
horizontal: 'left'
};
+
+ // 긴 텍스트 필드는 줄바꿈 허용
+ if (colNumber >= 5 && colNumber <= 6) { // itemList, subItemList
+ cell.alignment = {
+ vertical: 'top',
+ horizontal: 'left',
+ wrapText: true
+ };
+ }
});
});
- // 안내사항 워크시트 생성
+ // 안내사항 워크시트 생성 (새로운 스키마에 맞춰)
const guideSheet = workbook.addWorksheet('사용 가이드');
const guideData = [
- ['기술영업 벤더 가능 아이템 Import 템플릿', ''],
+ ['기술영업 벤더 가능 아이템 Import 템플릿 (새로운 스키마)', ''],
['', ''],
- ['📋 사용 방법:', ''],
+ ['📋 새로운 스키마 특징:', ''],
+ ['- 더욱 구체적인 아이템 정보 관리', ''],
+ ['- 공종과 선종으로 세분화된 분류', ''],
+ ['- 아이템 상세 설명 및 서브 아이템 정보', ''],
+ ['- 중복 아이템도 공종/선종이 다르면 별도 관리', ''],
+ ['', ''],
+ ['📌 필수 입력 필드:', ''],
+ ['1. 벤더이메일: 시스템에 등록된 벤더의 이메일 주소', ''],
+ [' 예: vendor@company.com', ''],
+ ['2. 아이템코드: 처리할 아이템의 고유 코드', ''],
+ [' 예: ITEM001, WELD_001, PAINT_002', ''],
+ ['', ''],
+ ['📝 선택 입력 필드:', ''],
+ ['3. 공종: 작업 유형 분류', ''],
+ [' 예: 용접, 도장, 기계, 전기, 배관 등', ''],
+ ['4. 선종: 적용 가능한 선박 유형', ''],
+ [' 예: 컨테이너선, 벌크선, 탱커, LNG선 등', ''],
+ [' - 여러 선종은 콤마로 구분: "컨테이너선, 벌크선"', ''],
+ ['5. 아이템리스트: 아이템에 대한 상세 설명', ''],
+ [' 예: "선체 용접 작업", "외판 도장 및 마감"', ''],
+ ['6. 서브아이템리스트: 세부 작업 항목들', ''],
+ [' 예: "외판 용접, 내부 구조 용접, 배관 용접"', ''],
+ ['7. 벤더코드: 기존 호환성을 위한 선택 필드', ''],
+ ['', ''],
+ ['🔍 중복 처리 로직:', ''],
+ ['- 동일한 벤더 + 아이템코드 + 공종 + 선종 = 중복으로 처리', ''],
+ ['- 아이템코드가 같아도 공종이나 선종이 다르면 별도 항목', ''],
+ ['- 예: ITEM001 + 용접 + 컨테이너선 ≠ ITEM001 + 도장 + 컨테이너선', ''],
+ ['', ''],
+ ['💡 사용 방법:', ''],
['1. "기술영업 벤더 가능 아이템" 시트에 데이터를 입력하세요', ''],
- ['2. 벤더 식별: 벤더코드 또는 벤더이메일 중 하나는 반드시 입력', ''],
- [' • 벤더코드가 있으면 벤더코드를 우선 사용', ''],
- [' • 벤더코드가 없으면 벤더이메일로 벤더 검색', ''],
- ['3. 아이템코드는 실제 존재하는 아이템코드를 사용하세요', ''],
- ['4. 한 아이템코드에 여러 벤더를 매핑할 수 있습니다 (1:N 관계)', ''],
- ['5. 중복된 벤더-아이템 조합은 무시됩니다', ''],
+ ['2. 필수 필드(벤더이메일, 아이템코드)는 반드시 입력', ''],
+ ['3. 선택 필드는 필요에 따라 입력 (빈 칸으로 두어도 됨)', ''],
+ ['4. 한 벤더가 여러 아이템을 담당할 수 있습니다 (1:N 관계)', ''],
+ ['5. 한 아이템에 여러 벤더를 배정할 수 있습니다 (N:M 관계)', ''],
['6. 파일 저장 후 시스템에서 업로드하세요', ''],
['', ''],
- ['⚠️ 중요 사항:', ''],
- ['- 벤더코드 또는 벤더이메일 중 하나는 반드시 필요', ''],
- ['- 벤더코드가 우선, 없으면 벤더이메일로 검색', ''],
- ['- 중복된 벤더-아이템 조합은 건너뜁니다', ''],
+ ['⚠️ 주의사항:', ''],
+ ['- 벤더이메일은 시스템에 이미 등록된 이메일이어야 함', ''],
+ ['- 이메일 형식 확인: @를 포함한 올바른 이메일 형식', ''],
+ ['- 아이템코드는 특수문자나 공백 주의', ''],
+ ['- 긴 텍스트 필드(아이템리스트, 서브아이템리스트)는 줄바꿈 가능', ''],
['- 오류가 있는 항목은 별도 파일로 다운로드됩니다', ''],
- ['- 빈 셀이 있으면 해당 행은 무시됩니다', ''],
['', ''],
- ['💡 팁:', ''],
- ['- 벤더코드만 존재하면 어떤 아이템코드든 입력 가능합니다', ''],
- ['- 아이템코드는 그대로 시스템에 저장됩니다', ''],
+ ['📊 데이터 예시:', ''],
+ ['벤더이메일: welding@company.com', ''],
+ ['아이템코드: WELD_HULL_001', ''],
+ ['공종: 용접', ''],
+ ['선종: 컨테이너선, 벌크선', ''],
+ ['아이템리스트: 선체 구조 용접 작업', ''],
+ ['서브아이템리스트: 외판 용접, 격벽 용접, 갑판 용접', ''],
['', ''],
['📞 문의사항이 있으시면 시스템 관리자에게 연락하세요.', ''],
];
@@ -104,16 +188,19 @@ export async function exportTechVendorPossibleItemsTemplate() {
if (index === 0) {
// 제목 스타일
row.getCell(1).font = { bold: true, size: 16, color: { argb: 'FF1F4E79' } };
+ } else if (rowData[0]?.includes('📋') || rowData[0]?.includes('📌') || rowData[0]?.includes('📝') || rowData[0]?.includes('🔍') || rowData[0]?.includes('💡') || rowData[0]?.includes('⚠️') || rowData[0]?.includes('📊')) {
+ // 섹션 제목 스타일 (이모지 포함)
+ row.getCell(1).font = { bold: true, color: { argb: 'FF1F4E79' } };
} else if (rowData[0]?.includes(':')) {
- // 섹션 제목 스타일
+ // 일반 제목 스타일
row.getCell(1).font = { bold: true, color: { argb: 'FF1F4E79' } };
- } else if (rowData[0]?.includes('•') || rowData[0]?.includes('-')) {
+ } else if (rowData[0]?.includes('-') || rowData[0]?.includes('•') || rowData[0]?.includes('예:')) {
// 리스트 아이템 스타일
row.getCell(1).font = { color: { argb: 'FF333333' } };
}
});
- guideSheet.getColumn(1).width = 70;
+ guideSheet.getColumn(1).width = 80;
guideSheet.getColumn(2).width = 20;
// 파일 생성 및 다운로드