From 7af366c595196fe61ed6ebf5912f54964a987299 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Wed, 13 May 2026 15:43:21 +0900 Subject: [PATCH] =?UTF-8?q?=EC=83=9D=EC=82=B0=EA=B4=80=EB=A6=AC>M-BOM=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=E2=80=94=20PR-A0=20=EC=9D=98=EC=A1=B4=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=8B=A0=EC=84=A4=20(mbom=5Fhist?= =?UTF-8?q?ory/sales=5Frequest=5Fmaster/client=5Fmng=20+=20user=5Fname=20f?= =?UTF-8?q?n)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이전 04cfac6e (구매관리>data-sync) 분류 정정: M-BOM 은 운영 wace "생산관리_M-BOM관리" 메뉴에 1:1 대응. docs/migration/purchase/ → docs/migration/production/ 폴더 rename. 신규 DDL (401_mbom_dependencies.sql): - mbom_history (8 cols) — M-BOM 변경 이력. FK→mbom_header CASCADE, PK objid, idx (header_objid, change_date) - sales_request_master (27 cols) — 구매요청서 마스터. PK objid, mbom_header_objid 컬럼(FK 없음), doc_type/recipient_ref/executor/title 등 M-BOM→PURCHASE 연계 컬럼, idx (doc_type, mbom_header_objid) - client_mng (117 cols) — 거래처 마스터. uk(client_cd), idx 3종 - user_name(varchar) PL/pgSQL — 그리드 WRITER_NAME/MBOM_EDITOR 표시용 (운영 mBomMgmtGridList:user_name(MH.WRITER) 1:1) 운영 sample 이관 (02_mbom_dependencies_sync.sql): - mbom_history 14 / sales_request_master 3 / client_mng 8,946 → RPS 전이 - staging 패턴(LIKE INCLUDING DEFAULTS + PK·FK·UK 제거) 으로 무결성 우회 - mbom_history: mbom_header 매칭 없는 행은 import 제외 (FK CASCADE 호환) - sales_request_master: mbom_header_objid 매칭 안 되면 NULL fallback 검증: - contract_mgmt.customer_objid LIKE 'C_%' → client_mng 매칭 성공 (운영 매퍼 CUSTOMER_NAME 분기 RPS 에서 그대로 동작) - user_name('admin') → '관리자' 반환 확인 - M-BOM 관리 화면 PR-A1 (그리드/검색/상세) 의 모든 의존 테이블 준비 완료 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../data-sync/01_mbom_sync.sql | 0 .../data-sync/02_mbom_dependencies_sync.sql | 66 +++++ .../ddl-extracted/400_mbom.sql | 0 .../ddl-extracted/401_mbom_dependencies.sql | 239 ++++++++++++++++++ 4 files changed, 305 insertions(+) rename docs/migration/{purchase => production}/data-sync/01_mbom_sync.sql (100%) create mode 100644 docs/migration/production/data-sync/02_mbom_dependencies_sync.sql rename docs/migration/{purchase => production}/ddl-extracted/400_mbom.sql (100%) create mode 100644 docs/migration/production/ddl-extracted/401_mbom_dependencies.sql diff --git a/docs/migration/purchase/data-sync/01_mbom_sync.sql b/docs/migration/production/data-sync/01_mbom_sync.sql similarity index 100% rename from docs/migration/purchase/data-sync/01_mbom_sync.sql rename to docs/migration/production/data-sync/01_mbom_sync.sql diff --git a/docs/migration/production/data-sync/02_mbom_dependencies_sync.sql b/docs/migration/production/data-sync/02_mbom_dependencies_sync.sql new file mode 100644 index 00000000..9139c807 --- /dev/null +++ b/docs/migration/production/data-sync/02_mbom_dependencies_sync.sql @@ -0,0 +1,66 @@ +-- ============================================================ +-- M-BOM 의존 테이블 운영 → RPS 데이터 이관 (PR-A0) +-- 운영: 211.115.91.141:11133/waceplm +-- 대상: 211.115.91.141:11134/vexplor_rps +-- +-- 함정: +-- 1) mbom_history.mbom_header_objid FK → 매칭 없는 행은 import 제외 (CASCADE 와 일치) +-- 2) sales_request_master.mbom_header_objid 는 FK 없음 (NULL 허용) +-- 3) client_mng 는 운영 8,946건 전량 이관 (그리드 CUSTOMER_NAME 매칭용) +-- +-- 실행 전 export (운영에서): +-- PGPASSWORD='waceplm0909!!' psql -h 211.115.91.141 -p 11133 -U postgres -d waceplm \ +-- -c "\copy (SELECT * FROM mbom_history) TO '/tmp/mbom_history.csv' WITH CSV HEADER" +-- PGPASSWORD='waceplm0909!!' psql -h 211.115.91.141 -p 11133 -U postgres -d waceplm \ +-- -c "\copy (SELECT * FROM sales_request_master) TO '/tmp/sales_request_master.csv' WITH CSV HEADER" +-- PGPASSWORD='waceplm0909!!' psql -h 211.115.91.141 -p 11133 -U postgres -d waceplm \ +-- -c "\copy (SELECT * FROM client_mng) TO '/tmp/client_mng.csv' WITH CSV HEADER" +-- ============================================================ + +-- ── 1. mbom_history ──────────────────────────────────────────── +DROP TABLE IF EXISTS mbom_history_stage; +CREATE TABLE mbom_history_stage (LIKE mbom_history INCLUDING DEFAULTS); +ALTER TABLE mbom_history_stage DROP CONSTRAINT IF EXISTS mbom_history_pkey; +ALTER TABLE mbom_history_stage DROP CONSTRAINT IF EXISTS fk_mbom_history_header; + +\copy mbom_history_stage FROM '/tmp/mbom_history.csv' WITH CSV HEADER + +-- RPS mbom_header 에 없는 mbom_header_objid 행은 import 제외 (FK CASCADE 호환) +DELETE FROM mbom_history_stage + WHERE NOT EXISTS (SELECT 1 FROM mbom_header WHERE objid = mbom_history_stage.mbom_header_objid); + +INSERT INTO mbom_history SELECT * FROM mbom_history_stage; +DROP TABLE mbom_history_stage; + + +-- ── 2. sales_request_master ──────────────────────────────────── +DROP TABLE IF EXISTS sales_request_master_stage; +CREATE TABLE sales_request_master_stage (LIKE sales_request_master INCLUDING DEFAULTS); +ALTER TABLE sales_request_master_stage DROP CONSTRAINT IF EXISTS sales_request_master_pkey; + +\copy sales_request_master_stage FROM '/tmp/sales_request_master.csv' WITH CSV HEADER + +-- mbom_header_objid 매칭 안 되는 경우 NULL (FK 는 없지만 그리드 매칭 시 NULL fallback) +UPDATE sales_request_master_stage SET mbom_header_objid = NULL + WHERE mbom_header_objid IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM mbom_header WHERE objid = sales_request_master_stage.mbom_header_objid); + +INSERT INTO sales_request_master SELECT * FROM sales_request_master_stage; +DROP TABLE sales_request_master_stage; + + +-- ── 3. client_mng ────────────────────────────────────────────── +DROP TABLE IF EXISTS client_mng_stage; +CREATE TABLE client_mng_stage (LIKE client_mng INCLUDING DEFAULTS); +ALTER TABLE client_mng_stage DROP CONSTRAINT IF EXISTS uk_client_mng_client_cd; + +\copy client_mng_stage FROM '/tmp/client_mng.csv' WITH CSV HEADER + +INSERT INTO client_mng SELECT * FROM client_mng_stage; +DROP TABLE client_mng_stage; + + +-- ── 결과 ────────────────────────────────────────────────────── +SELECT 'mbom_history' AS t, COUNT(*) FROM mbom_history +UNION ALL SELECT 'sales_request_master', COUNT(*) FROM sales_request_master +UNION ALL SELECT 'client_mng', COUNT(*) FROM client_mng; diff --git a/docs/migration/purchase/ddl-extracted/400_mbom.sql b/docs/migration/production/ddl-extracted/400_mbom.sql similarity index 100% rename from docs/migration/purchase/ddl-extracted/400_mbom.sql rename to docs/migration/production/ddl-extracted/400_mbom.sql diff --git a/docs/migration/production/ddl-extracted/401_mbom_dependencies.sql b/docs/migration/production/ddl-extracted/401_mbom_dependencies.sql new file mode 100644 index 00000000..a7199887 --- /dev/null +++ b/docs/migration/production/ddl-extracted/401_mbom_dependencies.sql @@ -0,0 +1,239 @@ +-- ============================================================ +-- M-BOM 관리 화면 의존 테이블 신설 (PR-A0) +-- 운영: 211.115.91.141:11133/waceplm +-- 대상: 211.115.91.141:11134/vexplor_rps +-- +-- 1) mbom_history — M-BOM 변경 이력 (8 cols, FK→mbom_header) +-- 2) sales_request_master — 구매요청서 마스터 (27 cols, FK→mbom_header via mbom_header_objid) +-- 3) client_mng — 거래처 마스터 (117 cols) — 그리드 CUSTOMER_NAME 매칭용 +-- +-- 생성 명령: +-- PGPASSWORD='vexplor0909!!' psql -h 211.115.91.141 -p 11134 -U postgres -d vexplor_rps -f 401_mbom_dependencies.sql +-- ============================================================ + +SET statement_timeout = 0; +SET client_encoding = 'UTF8'; + +-- ── 1. mbom_history ──────────────────────────────────────────── +CREATE TABLE IF NOT EXISTS public.mbom_history ( + objid character varying(64) NOT NULL, + mbom_header_objid character varying(64) NOT NULL, + change_type character varying(50), + change_description text, + before_data jsonb, + after_data jsonb, + change_user character varying(50), + change_date timestamp without time zone DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT mbom_history_pkey PRIMARY KEY (objid), + CONSTRAINT fk_mbom_history_header FOREIGN KEY (mbom_header_objid) + REFERENCES public.mbom_header(objid) ON DELETE CASCADE +); + +COMMENT ON TABLE public.mbom_history IS 'M-BOM 변경 이력 테이블'; + +CREATE INDEX IF NOT EXISTS idx_mbom_history_header_objid ON public.mbom_history (mbom_header_objid); +CREATE INDEX IF NOT EXISTS idx_mbom_history_change_date ON public.mbom_history (change_date); + + +-- ── 2. sales_request_master ──────────────────────────────────── +CREATE TABLE IF NOT EXISTS public.sales_request_master ( + objid character varying NOT NULL, + request_mng_no character varying, + request_cd character varying, + project_no character varying, + release_date character varying, + request_reasons character varying, + request_user_id character varying, + delivery_request_date character varying, + unit_name character varying, + status character varying, + receipt_user_id character varying, + receipt_date character varying, + writer character varying, + regdate timestamp without time zone, + remark character varying, + purchase_type character varying(50), + order_type character varying(50), + product_name character varying(50), + area_cd character varying(50), + customer_objid character varying(50), + paid_type character varying(20), + mbom_header_objid character varying(50), + doc_type character varying(50), + recipient_ref character varying(500), + executor character varying(100), + execution_date date, + title character varying(500), + CONSTRAINT sales_request_master_pkey PRIMARY KEY (objid) +); + +COMMENT ON TABLE public.sales_request_master IS '구매요청서 마스터'; +COMMENT ON COLUMN public.sales_request_master.request_mng_no IS '요청번호'; +COMMENT ON COLUMN public.sales_request_master.request_cd IS '구분'; +COMMENT ON COLUMN public.sales_request_master.project_no IS '프로젝트번호'; +COMMENT ON COLUMN public.sales_request_master.release_date IS '출고일'; +COMMENT ON COLUMN public.sales_request_master.request_reasons IS '요청사유'; +COMMENT ON COLUMN public.sales_request_master.request_user_id IS '요청인'; +COMMENT ON COLUMN public.sales_request_master.delivery_request_date IS '입고요청일'; +COMMENT ON COLUMN public.sales_request_master.unit_name IS '유닛명'; +COMMENT ON COLUMN public.sales_request_master.status IS '상태'; +COMMENT ON COLUMN public.sales_request_master.receipt_user_id IS '접수자'; +COMMENT ON COLUMN public.sales_request_master.receipt_date IS '접수일'; +COMMENT ON COLUMN public.sales_request_master.writer IS '작성자'; +COMMENT ON COLUMN public.sales_request_master.regdate IS '작성일'; +COMMENT ON COLUMN public.sales_request_master.remark IS '비고'; +COMMENT ON COLUMN public.sales_request_master.mbom_header_objid IS 'M-BOM 헤더 OBJID (NULL: 수동작성, 값 있음: M-BOM 자동생성)'; +COMMENT ON COLUMN public.sales_request_master.doc_type IS '문서유형 (PURCHASE_REQUEST: 구매요청서, PROPOSAL: 품의서)'; +COMMENT ON COLUMN public.sales_request_master.recipient_ref IS '수신및참조'; +COMMENT ON COLUMN public.sales_request_master.executor IS '시행자'; +COMMENT ON COLUMN public.sales_request_master.execution_date IS '시행일자'; +COMMENT ON COLUMN public.sales_request_master.title IS '제목'; + +CREATE INDEX IF NOT EXISTS idx_sales_request_master_doc_type ON public.sales_request_master (doc_type); +CREATE INDEX IF NOT EXISTS idx_sales_request_master_mbom_header ON public.sales_request_master (mbom_header_objid); + + +-- ── 3. client_mng ────────────────────────────────────────────── +CREATE TABLE IF NOT EXISTS public.client_mng ( + comp_code character varying(50), + client_cd character varying(50), + client_nm character varying(200), + tr_nmk character varying(200), + client_nmk character varying(200), + attr_nmk character varying(100), + client_type character varying(50), + bus_reg_no character varying(50), + resident_no character varying(50), + ceo_nm character varying(100), + ceo_nmk character varying(100), + bus_type character varying(100), + bus_item character varying(100), + post_no character varying(20), + addr1 character varying(300), + addr2 character varying(300), + addr_fg character varying(50), + tel_no character varying(50), + fax_no character varying(50), + homepage character varying(200), + email character varying(100), + liq_rs character varying(100), + tr_fg character varying(100), + country_nm character varying(100), + class_cd character varying(50), + class_nm character varying(100), + grade_cd character varying(50), + grade_nm character varying(100), + collect_client_cd character varying(50), + collect_client_nm character varying(200), + region_cd character varying(50), + region_nm character varying(100), + trade_start_dt character varying(20), + trade_end_dt character varying(20), + use_yn character varying(10), + contract_start_dt character varying(20), + contract_end_dt character varying(20), + trade_type character varying(50), + discount_rate character varying(20), + contract_amt character varying(20), + monthly_fee character varying(20), + payment_term character varying(200), + rcp_tp character varying(50), + credit_limit character varying(20), + limit_return_day character varying(20), + pur_bank_cd character varying(50), + pur_bank_nm character varying(200), + pur_branch_nm character varying(200), + pur_account_no character varying(100), + pur_account_holder character varying(100), + pur_pay_plan character varying(200), + pur_slip_type character varying(50), + pur_tax_type character varying(50), + sale_bank_cd character varying(50), + sale_bank_nm character varying(200), + sale_branch_nm character varying(200), + sale_account_no character varying(100), + sale_collect_plan character varying(200), + sale_slip_type character varying(50), + sale_tax_type character varying(50), + vendor_dept_nm character varying(100), + vendor_position character varying(50), + vendor_duty character varying(100), + vendor_manager_nm character varying(100), + vendor_tel character varying(50), + vendor_ext character varying(20), + vendor_mobile character varying(50), + vendor_email character varying(100), + mgr_dept_cd character varying(50), + mgr_dept_nm character varying(100), + mgr_position character varying(50), + mgr_duty character varying(100), + mgr_emp_cd character varying(50), + mgr_emp_nm character varying(100), + mgr_tel character varying(50), + mgr_ext character varying(20), + mgr_mobile character varying(50), + mgr_email character varying(100), + mgr_remark text, + rec_remark text, + rec_post_no character varying(20), + rec_addr1 character varying(300), + rec_addr2 character varying(300), + rec_addr_fg character varying(50), + rec_tel character varying(50), + rec_fax character varying(50), + project_cd character varying(50), + project_nm character varying(200), + pjt_nmk character varying(200), + ext_data_cd character varying(100), + e_tax_yn character varying(10), + unit_report_client character varying(200), + sub_bus_no character varying(50), + procurement_yn character varying(10), + user_def_dc1 character varying(200), + user_def_dc2 character varying(200), + use_fg character varying(50), + use_nm character varying(100), + bizcon_fg character varying(50), + bizcon_nm character varying(100), + ship_tp character varying(50), + ship_nm character varying(100), + plan_day_type character varying(50), + plan_day character varying(20), + purpose_type character varying(50), + for_yn character varying(10), + check_data character varying(200), + check_state character varying(100), + check_order character varying(100), + fixed_order character varying(100), + insert_id character varying(50), + insert_ip character varying(50), + insert_dt timestamp without time zone DEFAULT now(), + modify_id character varying(50), + modify_ip character varying(50), + modify_dt timestamp without time zone, + objid character varying, + CONSTRAINT uk_client_mng_client_cd UNIQUE (client_cd) +); + +CREATE INDEX IF NOT EXISTS idx_client_mng_client_cd ON public.client_mng (client_cd); +CREATE INDEX IF NOT EXISTS idx_client_mng_client_nm ON public.client_mng (client_nm); +CREATE INDEX IF NOT EXISTS idx_client_mng_use_yn ON public.client_mng (use_yn); + + +-- ── 4. user_name() 함수 ───────────────────────────────────────── +-- 그리드 WRITER_NAME / MBOM_EDITOR 표시용 (운영 1:1). +-- 매퍼 productionplanning.mBomMgmtGridList: user_name(MH.WRITER) / user_name(COALESCE(MH.EDITER, MH.WRITER)) + +CREATE OR REPLACE FUNCTION public.user_name(v_user_id character varying) +RETURNS character varying +LANGUAGE plpgsql +AS $function$ +DECLARE + v_user_name varchar; +BEGIN + SELECT user_name INTO v_user_name + FROM user_info + WHERE user_id = v_user_id; + RETURN v_user_name; +END; +$function$;