8453c425f8
'창고POG 출력' → 'POG 출력'. KO_EN 사전에 POG 출력/창고 POG 미리보기 추가해 ENG 모드서 영어 표시. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
189 lines
7.5 KiB
JavaScript
189 lines
7.5 KiB
JavaScript
/* 말레이시아 재고관리 — 화면 한글/영문 실시간 토글.
|
||
*
|
||
* - UI 고정 문구: 아래 KO_EN 사전으로 치환(요소 텍스트 = 한글 키).
|
||
* 대상 셀렉터는 UI 크롬(제목/헤더/버튼/라벨/배지/옵션/안내문)으로 한정 →
|
||
* 데이터 셀(상품코드/수량)은 건드리지 않음.
|
||
* - 상품명: 서버가 data-ko / data-en 을 함께 렌더 → 언어에 맞게 textContent 교체.
|
||
* - 선택값은 localStorage('mys_lang') 에 저장, 모든 화면 공통 적용.
|
||
*/
|
||
(function () {
|
||
"use strict";
|
||
|
||
var KO_EN = {
|
||
// 사이드바 메뉴 / 페이지 제목
|
||
"말레이시아 재고관리": "Malaysia Stock",
|
||
"입고/출고/조정 일괄 등록": "IN/OUT/ADJUST bulk",
|
||
// 탭 / 공통
|
||
"재고 현황": "Stock Status",
|
||
"입출고": "In / Out",
|
||
"일일 재고조사": "Daily Stocktake",
|
||
"창고 랙 보기": "Rack View",
|
||
"창고 랙": "Warehouse Rack",
|
||
"랙 보기": "Rack View",
|
||
"인쇄 미리보기": "Print Preview",
|
||
"인쇄": "Print",
|
||
"저장": "Save",
|
||
"닫기": "Close",
|
||
"칸을 드래그해 다른 칸으로 옮기면 구성이 이동(채워진 칸끼리는 맞교환)됩니다. 칸 번호는 그대로입니다. 인쇄할 칸은 체크 후 인쇄하세요.":
|
||
"Drag a cell onto another to move its contents (filled cells swap). Cell numbers stay. Check cells, then print.",
|
||
"기준 재고조사": "Based on stocktake",
|
||
"표시할 재고조사가 없습니다.": "No stocktake to display.",
|
||
"박스": "box",
|
||
"개": "ea",
|
||
"입수량": "Units/box",
|
||
"합계": "Subtotal",
|
||
"창고": "Warehouse",
|
||
"날짜": "Date",
|
||
"메모": "Memo",
|
||
"상태": "Status",
|
||
// 재고현황
|
||
"전산 재고 현황 — 낱개 기준": "System Stock — by Single",
|
||
"현재고 = 입고 − 출고 + 조정 + 재고조사반영 (콤보는 낱개로 분해 반영됨)":
|
||
"Current = IN − OUT + ADJUST + Stocktake (combos exploded to singles)",
|
||
"전산재고": "System Qty",
|
||
"조사수량": "Stocktake Qty",
|
||
"차이": "Diff",
|
||
"콤보 재고 (세트 단위)": "Combo Stock (by set)",
|
||
"콤보재고 = 재고조사": "Combo stock = stocktake",
|
||
"− 이후 출고": "− OUT since",
|
||
"재고조사 입력 없음": "No stocktake input",
|
||
"표시할 재고가 없습니다.": "No stock to display.",
|
||
"콤보 재고 입력이 없습니다.": "No combo stock input.",
|
||
"위험 구역 (슈퍼관리자)": "Danger Zone (Super Admin)",
|
||
"재고 초기화": "Reset Stock",
|
||
// 입출고
|
||
"등록 옵션": "Options",
|
||
"이동 종류 (낱개)": "Type (single)",
|
||
"IN (입고)": "IN (In)",
|
||
"OUT (출고)": "OUT (Out)",
|
||
"ADJUST (조정 ±)": "ADJUST (±)",
|
||
"입력": "Input",
|
||
"다운로드": "Download",
|
||
"낱개 상품": "Single Products",
|
||
"콤보 상품": "Combo Products",
|
||
"이동 이력": "Movement History",
|
||
"전체": "All",
|
||
"날짜해제": "Clear date",
|
||
"이동 이력이 없습니다.": "No movements.",
|
||
// 재고조사 목록
|
||
"재고조사 생성": "New Stocktake",
|
||
"조사 날짜": "Date",
|
||
"생성": "Create",
|
||
"생성 후 상세에서 낱개/세트 수량을 입력하고 확정하세요.":
|
||
"After creating, enter single/set qty in detail and finalize.",
|
||
"조사 목록": "Stocktake List",
|
||
"열기": "Open",
|
||
"삭제": "Delete",
|
||
"재고조사가 없습니다.": "No stocktakes.",
|
||
"확정": "Final",
|
||
"취소": "Cancel",
|
||
"작성중": "Draft",
|
||
// 재고조사 상세
|
||
"재고조사": "Stocktake",
|
||
"◀◀ 조사 목록": "◀◀ List",
|
||
"확정시각": "Finalized at",
|
||
"이전값 불러오기": "Load previous",
|
||
"입력 저장": "Save",
|
||
"확정 (전산 반영)": "Finalize (apply)",
|
||
"삭제 (슈퍼관리자)": "Delete (super)",
|
||
"랙 입력 (박스 단위)": "Rack Input (by box)",
|
||
"랙 칸에 아이템·입수량(박스당 개수)·박스 수를 입력하면 낱개/콤보 수량이 자동 집계됩니다. 한 칸에 여러 아이템은 + 로 추가하세요.":
|
||
"Enter item · units-per-box · box count in each rack cell; single/combo qty is auto-summed. Use + to add more items in one cell.",
|
||
"최종 계산 (낱개 기준)": "Final Calc (by single)",
|
||
"total_qty = direct_qty(낱개 직접) + from_set_qty(콤보 분해)":
|
||
"total_qty = direct_qty (single) + from_set_qty (combo)",
|
||
"입력된 수량이 없습니다.": "No quantities entered.",
|
||
// 표 헤더(한글만)
|
||
"이동일": "Date",
|
||
// 창고 랙 / POG
|
||
"POG 출력": "POG Print",
|
||
"창고 POG 미리보기": "Warehouse POG Preview",
|
||
};
|
||
|
||
var EN_KO = {};
|
||
Object.keys(KO_EN).forEach(function (k) { EN_KO[KO_EN[k]] = k; });
|
||
|
||
// 부분치환용 키 — 긴 키부터(부분 매칭 충돌 방지)
|
||
var RICH_KEYS = Object.keys(KO_EN).sort(function (a, b) { return b.length - a.length; });
|
||
|
||
// 헤더/사이드바처럼 .mys 밖이면서 KO 문구가 다른 텍스트와 섞인 요소.
|
||
// 사이드바는 현재 활성(말레이시아) 항목만 번역 → 다른 메뉴는 그대로 유지.
|
||
var RICH_SEL = [
|
||
".erp-topbar-title h1",
|
||
".erp-topbar-title p",
|
||
".erp-sidebar-item.is-active .erp-sidebar-label",
|
||
].join(",");
|
||
|
||
function applyRich(lang) {
|
||
document.querySelectorAll(RICH_SEL).forEach(function (el) {
|
||
if (el.getAttribute("data-o") === null) {
|
||
el.setAttribute("data-o", (el.textContent || "").trim());
|
||
}
|
||
var ko = el.getAttribute("data-o");
|
||
if (lang !== "en") { el.textContent = ko; return; }
|
||
var s = ko;
|
||
RICH_KEYS.forEach(function (k) {
|
||
if (s.indexOf(k) !== -1) s = s.split(k).join(KO_EN[k]);
|
||
});
|
||
el.textContent = s;
|
||
});
|
||
}
|
||
|
||
var SEL = [
|
||
".mys h1", ".mys h2", ".mys h3",
|
||
".mys th",
|
||
".mys label > span",
|
||
".mys button",
|
||
".mys a.erp-btn",
|
||
".mys .erp-muted",
|
||
".mys option",
|
||
".mys .erp-badge",
|
||
".mys .i18n",
|
||
].join(",");
|
||
|
||
function applyLang(lang) {
|
||
// 1) 상품명(한/영 동시 보유)
|
||
document.querySelectorAll(".mys [data-ko][data-en]").forEach(function (el) {
|
||
el.textContent = (lang === "en") ? el.getAttribute("data-en")
|
||
: el.getAttribute("data-ko");
|
||
});
|
||
// 2) UI 고정 문구
|
||
document.querySelectorAll(SEL).forEach(function (el) {
|
||
// 자식 요소가 있는 컨테이너는 건너뜀(.i18n 로 명시한 경우만 허용)
|
||
if (el.children.length && !el.classList.contains("i18n")) return;
|
||
if (el.hasAttribute("data-ko") && el.hasAttribute("data-en")) return; // 이미 처리됨
|
||
if (el.getAttribute("data-o") === null) {
|
||
el.setAttribute("data-o", (el.textContent || "").trim());
|
||
}
|
||
var ko = el.getAttribute("data-o");
|
||
if (lang === "en") {
|
||
if (KO_EN[ko] !== undefined) el.textContent = KO_EN[ko];
|
||
} else {
|
||
el.textContent = ko;
|
||
}
|
||
});
|
||
// 3) 헤더/사이드바(부분 치환)
|
||
applyRich(lang);
|
||
// 4) 토글 버튼 라벨
|
||
var btn = document.getElementById("mys-lang-toggle");
|
||
if (btn) btn.textContent = (lang === "en") ? "한글" : "ENG";
|
||
document.documentElement.setAttribute("data-mys-lang", lang);
|
||
}
|
||
|
||
function current() {
|
||
return localStorage.getItem("mys_lang") === "en" ? "en" : "ko";
|
||
}
|
||
|
||
function toggle() {
|
||
var next = current() === "en" ? "ko" : "en";
|
||
localStorage.setItem("mys_lang", next);
|
||
applyLang(next);
|
||
}
|
||
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
var btn = document.getElementById("mys-lang-toggle");
|
||
if (btn) btn.addEventListener("click", toggle);
|
||
applyLang(current());
|
||
});
|
||
})();
|