diff --git a/docs/migration/purchase/data-sync/01_mbom_sync.sql b/docs/migration/purchase/data-sync/01_mbom_sync.sql new file mode 100644 index 00000000..77f8420e --- /dev/null +++ b/docs/migration/purchase/data-sync/01_mbom_sync.sql @@ -0,0 +1,63 @@ +-- ============================================================ +-- M-BOM 운영 sample 데이터 → RPS 이관 +-- 운영: 211.115.91.141:11133/waceplm (mbom_header 3건, mbom_detail 95건) +-- 대상: 211.115.91.141:11134/vexplor_rps +-- +-- 함정: +-- 1) mbom_header.source_ebom_objid → RPS part_bom_report 에 없는 OBJID 는 NULL 처리 +-- 2) mbom_detail.part_objid varchar → RPS bigint (FK part_mng.objid bigint 호환) +-- 3) RPS part_mng 에 없는 part_objid 도 NULL 처리 +-- +-- 실행 전: /tmp/mbom_header.csv, /tmp/mbom_detail.csv 준비 (운영DB \copy TO) +-- ============================================================ + +-- ── mbom_header ─────────────────────────────────────────────── +DROP TABLE IF EXISTS mbom_header_stage; +CREATE TABLE mbom_header_stage (LIKE mbom_header INCLUDING DEFAULTS); +ALTER TABLE mbom_header_stage DROP CONSTRAINT IF EXISTS mbom_header_pkey; +ALTER TABLE mbom_header_stage DROP CONSTRAINT IF EXISTS mbom_header_mbom_no_key; +ALTER TABLE mbom_header_stage DROP CONSTRAINT IF EXISTS fk_mbom_source_ebom; +ALTER TABLE mbom_header_stage DROP CONSTRAINT IF EXISTS fk_mbom_source_mbom; + +\copy mbom_header_stage FROM '/tmp/mbom_header.csv' WITH CSV HEADER + +-- RPS part_bom_report 에 없는 source_ebom_objid 는 NULL +UPDATE mbom_header_stage SET source_ebom_objid = NULL + WHERE source_ebom_objid IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM part_bom_report WHERE objid = mbom_header_stage.source_ebom_objid); + +-- self FK source_mbom_objid: 자기 자신 OBJID 셋에 있으면 OK, 아니면 NULL +UPDATE mbom_header_stage SET source_mbom_objid = NULL + WHERE source_mbom_objid IS NOT NULL + AND source_mbom_objid NOT IN (SELECT objid FROM mbom_header_stage); + +INSERT INTO mbom_header SELECT * FROM mbom_header_stage; +DROP TABLE mbom_header_stage; + +-- ── mbom_detail ──────────────────────────────────────────────── +DROP TABLE IF EXISTS mbom_detail_stage; +CREATE TABLE mbom_detail_stage (LIKE mbom_detail INCLUDING DEFAULTS); +ALTER TABLE mbom_detail_stage DROP CONSTRAINT IF EXISTS mbom_detail_pkey; +ALTER TABLE mbom_detail_stage DROP CONSTRAINT IF EXISTS fk_mbom_detail_header; +ALTER TABLE mbom_detail_stage DROP CONSTRAINT IF EXISTS fk_mbom_detail_part; +ALTER TABLE mbom_detail_stage ALTER COLUMN part_objid TYPE varchar(64) USING part_objid::text; + +\copy mbom_detail_stage FROM '/tmp/mbom_detail.csv' WITH CSV HEADER + +-- RPS part_mng 에 없는 part_objid 는 NULL (bigint 형변환 안전) +UPDATE mbom_detail_stage SET part_objid = NULL + WHERE part_objid IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM part_mng WHERE objid::text = mbom_detail_stage.part_objid); + +-- RPS mbom_header 에 없는 mbom_header_objid 행은 import 제외 +DELETE FROM mbom_detail_stage + WHERE NOT EXISTS (SELECT 1 FROM mbom_header WHERE objid = mbom_detail_stage.mbom_header_objid); + +-- bigint 형변환 후 본 테이블 INSERT +ALTER TABLE mbom_detail_stage ALTER COLUMN part_objid TYPE bigint USING part_objid::bigint; +INSERT INTO mbom_detail SELECT * FROM mbom_detail_stage; +DROP TABLE mbom_detail_stage; + +-- ── 결과 ────────────────────────────────────────────────────── +SELECT 'mbom_header' AS t, COUNT(*) FROM mbom_header +UNION ALL SELECT 'mbom_detail', COUNT(*) FROM mbom_detail; diff --git a/docs/migration/purchase/ddl-extracted/400_mbom.sql b/docs/migration/purchase/ddl-extracted/400_mbom.sql new file mode 100644 index 00000000..b7739db0 --- /dev/null +++ b/docs/migration/purchase/ddl-extracted/400_mbom.sql @@ -0,0 +1,125 @@ +-- ============================================================ +-- M-BOM (Manufacturing BOM) — 구매관리/생산관리 공유 마스터 +-- 원본: 운영DB 211.115.91.141:11133/waceplm +-- 추출일: 2026-05-13 +-- 적용대상: vexplor_rps (11134) +-- +-- 의존성: +-- mbom_header.source_ebom_objid → part_bom_report.objid (개발관리 E-BOM, varchar) +-- mbom_detail.mbom_header_objid → mbom_header.objid (varchar, CASCADE) +-- mbom_detail.part_objid → part_mng.objid (개발관리 PART, **RPS 에서 bigint**, SET NULL) +-- +-- 운영DB ↔ RPS 타입 차이 (feedback_createobjid_pattern.md): +-- 운영DB: part_mng.objid varchar(64) → mbom_detail.part_objid varchar(64) +-- RPS: part_mng.objid bigint → mbom_detail.part_objid bigint (FK 호환) +-- 운영 데이터 임포트 시 part_objid::bigint cast 필요. +-- +-- 비즈니스 흐름: +-- M-BOM 생성 → 구매리스트(sales_request_master + mbom_detail) → +-- 견적요청서 / 품의서(sales_request_detail) → +-- 발주서(purchase_order_master + purchase_order_part) → +-- 입고(arrival_plan + inventory_mgmt + inventory_mgmt_in) +-- ============================================================ + +-- ── 1. mbom_header (M-BOM 마스터 헤더) ──────────────────────── +CREATE TABLE IF NOT EXISTS mbom_header ( + objid varchar(64) NOT NULL, + mbom_no varchar(100) NOT NULL, + source_bom_type varchar(20), + source_ebom_objid varchar(64), + source_mbom_objid varchar(64), + project_objid varchar(64), + contract_objid varchar(64), + part_no varchar(100), + part_name varchar(200), + revision varchar(50), + status varchar(20) DEFAULT 'Y', + mbom_status varchar(20) DEFAULT 'DRAFT', + production_type varchar(50), + total_cost numeric(15,2), + writer varchar(50), + regdate timestamp DEFAULT CURRENT_TIMESTAMP, + editer varchar(50), + edit_date timestamp, + approver varchar(50), + approve_date timestamp, + remark text, + CONSTRAINT mbom_header_pkey PRIMARY KEY (objid), + CONSTRAINT mbom_header_mbom_no_key UNIQUE (mbom_no), + CONSTRAINT fk_mbom_source_ebom FOREIGN KEY (source_ebom_objid) + REFERENCES part_bom_report(objid) ON DELETE SET NULL, + CONSTRAINT fk_mbom_source_mbom FOREIGN KEY (source_mbom_objid) + REFERENCES mbom_header(objid) ON DELETE SET NULL +); + +CREATE INDEX IF NOT EXISTS idx_mbom_header_mbom_no ON mbom_header (mbom_no); +CREATE INDEX IF NOT EXISTS idx_mbom_header_project_objid ON mbom_header (project_objid); +CREATE INDEX IF NOT EXISTS idx_mbom_header_source_ebom ON mbom_header (source_ebom_objid); +CREATE INDEX IF NOT EXISTS idx_mbom_header_source_mbom ON mbom_header (source_mbom_objid); +CREATE INDEX IF NOT EXISTS idx_mbom_header_source_type ON mbom_header (source_bom_type); +CREATE INDEX IF NOT EXISTS idx_mbom_header_status ON mbom_header (status); + +-- ── 2. mbom_detail (M-BOM 상세 트리: 부모-자식 + qty/단가/공급처) ── +CREATE TABLE IF NOT EXISTS mbom_detail ( + objid varchar(64) NOT NULL, + mbom_header_objid varchar(64) NOT NULL, + parent_objid varchar(64), + child_objid varchar(64), + seq integer, + level integer, + part_objid bigint, + part_no varchar(100), + part_name varchar(200), + qty numeric(15,4), + unit varchar(20), + supply_type varchar(50), + make_or_buy varchar(20), + raw_material_part_no varchar(100), + raw_material_spec varchar(200), + raw_material varchar(100), + raw_material_size varchar(100), + processing_vendor varchar(100), + processing_deadline varchar(10), + grinding_deadline varchar(10), + required_qty numeric(15,4), + order_qty numeric(15,4), + production_qty numeric(15,4), + stock_qty numeric(15,4), + shortage_qty numeric(15,4), + vendor varchar(100), + unit_price numeric(15,2), + total_price numeric(15,2), + currency varchar(10) DEFAULT 'KRW', + lead_time integer, + min_order_qty numeric(15,4), + status varchar(20) DEFAULT 'ACTIVE', + regdate timestamp DEFAULT CURRENT_TIMESTAMP, + writer varchar(50), + edit_date timestamp, + editer varchar(50), + remark text, + use_yn varchar(1) DEFAULT 'Y', + net_qty numeric DEFAULT 0, + po_qty numeric DEFAULT 0, + proposal_date date, + processing_unit_price numeric(15,2), + processing_total_price numeric(15,2), + grand_total_price numeric(15,2), + processing_proposal_date date, + delivery_request_date varchar(10), + item_qty numeric(15,4), + CONSTRAINT mbom_detail_pkey PRIMARY KEY (objid), + CONSTRAINT fk_mbom_detail_header FOREIGN KEY (mbom_header_objid) + REFERENCES mbom_header(objid) ON DELETE CASCADE, + CONSTRAINT fk_mbom_detail_part FOREIGN KEY (part_objid) + REFERENCES part_mng(objid) ON DELETE SET NULL +); + +CREATE INDEX IF NOT EXISTS idx_mbom_detail_header_objid ON mbom_detail (mbom_header_objid); +CREATE INDEX IF NOT EXISTS idx_mbom_detail_parent_objid ON mbom_detail (parent_objid); +CREATE INDEX IF NOT EXISTS idx_mbom_detail_part_no ON mbom_detail (part_no); +CREATE INDEX IF NOT EXISTS idx_mbom_detail_part_objid ON mbom_detail (part_objid); +CREATE INDEX IF NOT EXISTS idx_mbom_detail_proposal_date ON mbom_detail (proposal_date) WHERE proposal_date IS NULL; + +COMMENT ON TABLE mbom_header IS 'M-BOM 마스터 헤더 (제조용 BOM, E-BOM 파생/템플릿/복사)'; +COMMENT ON TABLE mbom_detail IS 'M-BOM 상세 트리 (부모-자식 구조 + 수량/단가/공급처/원자재)';