1760045634
- wace_plm contract_mgmt/contract_item/contract_item_serial/contract_mgmt_option/estimate_template/estimate_template_item/mail_log/sales_registration/shipment_log 9개 테이블 DDL을 vexplor_rps에 적재, 운영 데이터 복사 - 거래처: Wehago/Amaranth ERP api16S11 INBOUND 동기화 결과(customer_code) 기준 LEFT JOIN으로 변경, 25/25 매칭 - 품목: wace part_mng 8,179건을 item_info(varchar id)에 wace objid 그대로 INSERT, contract_item 72/72 매칭 - 공통코드: wace comm_code 847건 복제 + backend SQL에 5종 LEFT JOIN - DataGrid에 formatMoney(천단위콤마+소수점2자리) / formatNumber 자동 우측정렬 분리 - adminService.getUserMenuList company_code 분기 제거(RPS 단독), useMenu.buildMenuTree root 식별 보강 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8.5 KiB
8.5 KiB
03. 판매관리 이식 상세
원본:
/contractMgmt/salesMgmtList.do(위임) →/salesNcollectMgmt/sales.do또는/salesMgmt/salesMgmtJSP:salesmgmt/salesMgmt/salesMgmtList.jsp(34KB) Controller:SalesNcollectMgmtController(line 763~) 대상:app/(main)/COMPANY_16/sales/sale/page.tsx(신규)
1. 화면 구조 (wace_plm 원본)
수주된 항목을 출하지시 → 판매등록 → 거래명세서 발행까지 처리.
1.1 검색 폼
| 필드 | name | 타입 | 비고 |
|---|---|---|---|
| 주문유형 | orderType |
select2 (공통코드) | |
| 발주번호 | poNo |
text | |
| 고객사 | customer_objid |
select2 | |
| 품번 | search_partNo |
select2-part | hidden search_partObjId |
| 품명 | search_partName |
select2-part | |
| 시리얼 | serialNo |
text | |
| 출하상태 | shippingStatus |
select2 | |
| 발주일 from~to | orderDateFrom / orderDateTo |
date_icon | |
| 출하일 from~to | shippingDateFrom / shippingDateTo |
date_icon | |
| 판매상태 | salesStatus |
select2 multiple | 다중 선택 |
1.2 버튼
| 버튼 | id | 동작 |
|---|---|---|
| 조회 | btnSearch |
/salesMgmt/salesMgmtGridList.do |
| 출하지시/판매등록 | btnBulkRegister |
(녹색) → /salesMgmt/salesRegForm.do 새창 |
| (주석) | 매출관리에서 사용 | |
| (주석) | /salesMgmt/splitShipmentForm.do |
1.3 그리드 컬럼
데이터 소스: POST /salesMgmt/salesMgmtGridList.do
| # | 컬럼 | field | 정렬 |
|---|---|---|---|
| 1 | 프로젝트번호 | PROJECT_NO | center, frozen |
| 2 | 주문유형 | ORDER_TYPE | center |
| 3 | 발주일 | ORDER_DATE | center |
| 4 | 발주번호 | PO_NO | center |
| 5 | 요청납기 | REQUEST_DATE | center |
| 6 | 출하일 | SHIPPING_DATE_WITH_COUNT | center |
| 7 | 고객사 | CUSTOMER | left |
| 8 | 품명 | PRODUCT_NAME | left |
| 9 | 수주수량 | ORDER_QUANTITY | right |
| 10 | 판매수량 | SALES_QUANTITY | right |
| 11 | 잔량 | REMAINING_QUANTITY | right |
| 12 | 판매단가 | SALES_UNIT_PRICE | right |
| 13 | 판매공급가액 | SALES_SUPPLY_PRICE | right |
| 14 | 부가세 | SALES_VAT | right |
| 15 | 판매총액 | SALES_TOTAL_AMOUNT | right |
| 16 | 판매원화총액 | SALES_TOTAL_AMOUNT_KRW | right |
| 17 | 잔량원화총액 | REMAINING_AMOUNT_KRW | right |
| 18 | 수주상태 | ORDER_STATUS | center |
| 19 | 판매상태 | SALES_STATUS | center |
| 20 | 생산상태 | PRODUCTION_STATUS | center |
| 21 | 출하지시상태 | SHIPPING_ORDER_STATUS | center |
| 22 | 유/무상 | PAYMENT_TYPE | center |
| 23 | 환종 | SALES_CURRENCY_NAME | center |
| 24 | 환율 | SALES_EXCHANGE_RATE | right |
| 25 | S/N | SERIAL_NO | left |
| 26 | 분할S/N | SPLIT_SERIAL_NO | left |
| 27 | 품번 | PRODUCT_NO | left |
| 28 | 제품구분 | PRODUCT_TYPE | center |
| 29 | 국내/해외 | NATION | center |
| 30 | 접수일 | RECEIPT_DATE | center |
| 31 | 고객사요청사항 | CUSTOMER_REQUEST | left |
| 32 | 주문서첨부 | CU01_CNT | center |
| 33 | 출하방법 | SHIPPING_METHOD | center |
| 34 | 담당자 | MANAGER | center |
| 35 | 인도조건 | INCOTERMS | center |
| 36 | 거래명세서 | TRANSACTION_STATEMENT | center |
2. 백엔드 endpoint 매핑
| wace_plm endpoint | 메서드 | 용도 | vexplor_rps 신규 endpoint |
|---|---|---|---|
/contractMgmt/salesMgmtList.do |
GET | (위임) → /salesmgmt/salesMgmt/salesMgmtList 렌더 |
(Next.js page) |
/salesNcollectMgmt/sales.do |
GET | 판매 화면 직접 진입 | (Next.js page) |
/salesMgmt/salesMgmtGridList.do |
POST | 그리드 데이터 | GET /api/sales/sale/list?... |
/salesMgmt/salesRegForm.do |
GET | 출하지시/판매등록 폼 | app/(pop)/sales/sale/register/page.tsx (43KB JSP) |
/salesMgmt/saveSales.do |
POST | 판매 저장 | POST /api/sales/sale |
/salesMgmt/splitShipmentForm.do |
GET | 분할출하 폼 | app/(pop)/sales/sale/split/page.tsx (23KB JSP) |
/salesMgmt/saveSplitShipment.do |
POST | 분할출하 저장 | POST /api/sales/sale/split |
/salesMgmt/shippingDetailPopup.do |
GET | 출하 상세 팝업 | (Next.js Dialog) |
/salesMgmt/transactionStatementForm.do |
GET | 거래명세서 폼 | app/(pop)/sales/sale/transaction/page.tsx (31KB JSP) |
/salesMgmt/getTransactionStatementData.do |
POST | 거래명세서 데이터 | GET /api/sales/sale/transaction-statement?... |
/salesMgmt/saveTransactionStatement.do |
POST | 거래명세서 저장 | POST /api/sales/sale/transaction-statement |
/salesMgmt/getSavedTransactionStatement.do |
POST | 저장된 거래명세서 조회 | GET /api/sales/sale/transaction-statement/:id |
/salesMgmt/getAllSerialNumbers.do |
POST | 시리얼 번호 일괄 조회 | (주문과 공유 가능) |
/salesNcollectMgmt/contractList.do |
GET | (대시보드 화면) | TBD |
/salesNcollectMgmt/salesMgmtFormPopup.do |
GET | 판매 폼 팝업 (구버전) | (사용 안할 듯) |
/salesNcollectMgmt/saveSalesMgmt.do |
POST | 판매 저장 (구버전) | 위와 통합 |
/salesNcollectMgmt/deleteSalesMgmt.do |
POST | 판매 삭제 | DELETE /api/sales/sale/:id |
/salesNcollectMgmt/salesDeadlineConfirm.do |
POST | 매출 마감 확인 | (매출관리에서 호출) |
3. DB 테이블
2026-05-07 운영 DB 직접 확인 결과:
transaction_statement_*테이블은 존재하지 않음. 거래명세서는 별도 테이블 없이 화면 폼에서 출력만 하거나, attach_file_info에 PDF로 저장하는 방식으로 보임 (정확한 위치는getSavedTransactionStatement.doSQL 분석 필요).
| 테이블 | 역할 | DDL |
|---|---|---|
sales_registration |
판매 등록 헤더 (프로젝트당 1건, UNIQUE project_no) — 메인 |
ddl-extracted/101_create_sales_registration.sql |
shipment_log |
분할출하 이력 라인 (FK parent_sale_no → sales_registration) |
위 |
contract_mgmt |
수주 헤더 (조인 필수, target_objid로 연결) | db/dbexport.pgsql:2488 |
contract_item |
수주 라인 (조인 필수) | database/contract_item_tables.sql |
contract_item_serial |
시리얼 (분할출하 시 분리) | 위 |
production_result |
생산 결과 (조인 — PRODUCTION_STATUS) |
(참고만) |
핵심 관계
contract_mgmt (수주 헤더)
└─ contract_item (수주 라인)
└─ contract_item_serial (라인별 S/N)
contract_mgmt.objid = sales_registration.project_no? (정확한 매칭 키 확인 필요)
= shipment_log.target_objid
sales_registration (판매 헤더, 프로젝트당 1건)
↑ parent_sale_no
└─ shipment_log (분할출하 + 매출마감 이력 N건)
⚠️
sales_registration.project_no와contract_mgmt.objid(또는contract_no)의 매칭 키는 운영 SQL에서 재확인 필요. 칼럼명은project_no이지만 실제로는 contract_mgmt를 가리킬 가능성이 큼.
4. 구현 순서
- 운영 DB DDL 추출 (sales_registration, shipment_log, transaction_statement)
- 마이그레이션 SQL:
db/migrations/102_create_sale_tables.sql - 백엔드:
backend-node/src/routes/saleRoutes.tsbackend-node/src/services/saleService.ts(그리드 SQL은 contract_mgmt + contract_item + sales_registration JOIN, 잔량 계산 = ORDER_QUANTITY - SUM(SALES_QUANTITY))- 분할출하 트랜잭션 (라인 분리 + 시리얼 재할당)
- 프론트엔드:
frontend/app/(main)/COMPANY_16/sales/sale/page.tsx(목록)app/(pop)/sales/sale/register/page.tsx(출하지시/판매등록 폼)app/(pop)/sales/sale/split/page.tsx(분할출하)app/(pop)/sales/sale/transaction/page.tsx(거래명세서)
5. 주의사항
- 잔량(REMAINING_QUANTITY) 계산:
ORDER_QUANTITY - SUM(sales_registration.SALES_QUANTITY where contract_item_objid = ?). 그리드는 라인 단위 또는 헤더 단위 표시 모드가 있을 수 있음 — 원본 SQL 확인 필요. - 분할출하: 한 라인의 시리얼을 여러 출하건으로 나누는 시나리오. UI 복잡도 높음.
- 거래명세서: 여러 판매건을 묶어 1장으로 발행.
projectNos파라미터로 다건 처리. - 상태 컬럼들: ORDER_STATUS / SALES_STATUS / PRODUCTION_STATUS / SHIPPING_ORDER_STATUS 4개를 동시 표시 — 각 상태 머신 정의 필요.
- 환율 컬럼 분리: 수주(
exchange_rate)와 판매(sales_exchange_rate)를 별도 보유 — 시점 환율을 잠그는 정책. - 거래명세서 PDF: 한국어 양식, 워터마크/도장 처리 필요할 수 있음.