17b08c7a09
- backend purchaseOrderMailService 신설 — getOrderMailInfo / getPartnerManagerList / sendOrderMail (SMTP PURCHASE, 발송 성공 시 mail_send_yn='Y'/mail_send_date 갱신) - backend routes — GET /order-form/mail-info/:objid, POST /order-form/mail, GET /options/partner-managers/:partnerObjid - frontend lib/utils/purchaseOrderPdf — html2canvas-pro + jsPDF (A4, scale=2, input/textarea → 텍스트 변환). download:true 면 파일 저장, 아니면 base64 반환 - PurchaseOrderMailDialog 신설 — EstimateMailDialog 패턴 단순화 (한글/영문 본문 분기, 공급업체 단일 email 자동 채움) - 3개 양식 다이얼로그 — 읽기전용 + 저장된 발주서일 때 "메일 발송" + "PDF 다운로드" 버튼 노출. window.print 간이판 제거 - 3개 양식 다이얼로그 — "행 추가"/"선택 행 삭제" 버튼 + 그리드 체크박스 컬럼 제거 (wace 운영판은 모두 주석 처리/부재. 발주서는 품의서에서 자동 채움된 품목 그대로 사용)
60 lines
2.3 KiB
TypeScript
60 lines
2.3 KiB
TypeScript
// 발주서 다이얼로그 컨테이너 DOM → PDF base64 변환 헬퍼.
|
|
// 영업관리 estimate template2 (lib + sales/estimate/template2/pop/page.tsx 372-438) 패턴 단순화 버전.
|
|
// - 다이얼로그 안의 양식 컨테이너를 html2canvas-pro 로 캡처 (scale=2, 흰배경, input/textarea → 텍스트)
|
|
// - A4 비율로 jsPDF 에 그려 datauristring 반환 (메일 첨부) 또는 save (파일 다운로드)
|
|
|
|
export async function generatePurchaseOrderPdf(
|
|
container: HTMLElement,
|
|
opts?: { filename?: string; download?: boolean },
|
|
): Promise<string> {
|
|
const html2canvas = (await import("html2canvas-pro")).default;
|
|
const jspdfModule: any = await import("jspdf");
|
|
const jsPDF = jspdfModule.jsPDF ?? jspdfModule.default;
|
|
|
|
const canvas = await html2canvas(container, {
|
|
scale: 2,
|
|
useCORS: true,
|
|
backgroundColor: "#ffffff",
|
|
onclone: (doc) => {
|
|
// input/textarea/select → 텍스트로 교체 (편집 윤곽 제거)
|
|
doc.querySelectorAll("input, textarea").forEach((el) => {
|
|
const v = (el as HTMLInputElement | HTMLTextAreaElement).value ?? "";
|
|
const span = doc.createElement("span");
|
|
span.textContent = v;
|
|
(span.style as any).whiteSpace = "pre-wrap";
|
|
el.parentNode?.replaceChild(span, el);
|
|
});
|
|
// ShadCN Select 트리거 안의 표시 텍스트만 추출 — 화살표/아이콘은 제거
|
|
doc.querySelectorAll('[role="combobox"]').forEach((el) => {
|
|
const text = el.textContent ?? "";
|
|
const span = doc.createElement("span");
|
|
span.textContent = text.trim();
|
|
el.parentNode?.replaceChild(span, el);
|
|
});
|
|
},
|
|
});
|
|
|
|
const pdf = new jsPDF("p", "mm", "a4");
|
|
const imgData = canvas.toDataURL("image/jpeg", 0.85);
|
|
const imgWidth = 210;
|
|
const pageHeight = 297;
|
|
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
|
|
|
let heightLeft = imgHeight;
|
|
let position = 0;
|
|
pdf.addImage(imgData, "JPEG", 0, position, imgWidth, imgHeight, undefined, "FAST");
|
|
heightLeft -= pageHeight;
|
|
|
|
while (heightLeft > 0) {
|
|
position = heightLeft - imgHeight;
|
|
pdf.addPage();
|
|
pdf.addImage(imgData, "JPEG", 0, position, imgWidth, imgHeight, undefined, "FAST");
|
|
heightLeft -= pageHeight;
|
|
}
|
|
|
|
if (opts?.download) {
|
|
pdf.save(opts.filename ?? "purchase_order.pdf");
|
|
}
|
|
return pdf.output("datauristring") as string;
|
|
}
|