Merge pull request 'V20260210' (#163) from V20260210 into main
Reviewed-on: #163
This commit was merged in pull request #163.
This commit is contained in:
@@ -844,19 +844,22 @@
|
||||
FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID) AS PAYMENT_TYPE,
|
||||
T.PART_NO AS PRODUCT_NO,
|
||||
T.PART_NAME AS PRODUCT_NAME,
|
||||
-- S/N: 해당 품목의 시리얼 번호 (여러 개일 경우 "S/N 외 N건" 형식)
|
||||
(SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 0 THEN ''
|
||||
WHEN COUNT(*) = 1 THEN MIN(CIS.SERIAL_NO)
|
||||
ELSE MIN(CIS.SERIAL_NO) || ' 외 ' || (COUNT(*) - 1)::TEXT || '건'
|
||||
END
|
||||
FROM CONTRACT_ITEM CI
|
||||
LEFT JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND CIS.SERIAL_NO IS NOT NULL) AS SERIAL_NO,
|
||||
-- S/N: CONTRACT_ITEM_SERIAL(마스터) 우선, 없으면 판매등록 텍스트 fallback (그리드 요약용)
|
||||
COALESCE(
|
||||
(SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 0 THEN NULL
|
||||
WHEN COUNT(*) = 1 THEN MIN(CIS.SERIAL_NO)
|
||||
ELSE MIN(CIS.SERIAL_NO) || ' 외 ' || (COUNT(*) - 1)::TEXT || '건'
|
||||
END
|
||||
FROM CONTRACT_ITEM CI
|
||||
LEFT JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND CIS.SERIAL_NO IS NOT NULL),
|
||||
SR.serial_no
|
||||
) AS SERIAL_NO,
|
||||
COALESCE(T.QUANTITY::numeric, 0) AS ORDER_QUANTITY,
|
||||
-- 요청납기: CONTRACT_ITEM 우선, 없으면 PROJECT_MGMT, 없으면 CONTRACT_MGMT
|
||||
COALESCE(
|
||||
@@ -893,20 +896,10 @@
|
||||
COALESCE(SR.sales_vat, 0) AS SALES_VAT,
|
||||
COALESCE(SR.sales_total_amount, 0) AS SALES_TOTAL_AMOUNT,
|
||||
COALESCE(SR.sales_total_amount, 0) AS SALES_TOTAL_AMOUNT_KRW,
|
||||
-- 잔량 계산: 수주수량 - shipment_log의 split_quantity 합계
|
||||
COALESCE(T.QUANTITY::numeric, 0) - COALESCE(
|
||||
(SELECT SUM(COALESCE(split_quantity, 0))
|
||||
FROM shipment_log
|
||||
WHERE target_objid = T.PROJECT_NO),
|
||||
0
|
||||
) AS REMAINING_QUANTITY,
|
||||
-- 잔량원화총액 계산: (수주수량 - shipment_log 합계) * 판매단가
|
||||
(COALESCE(T.QUANTITY::numeric, 0) - COALESCE(
|
||||
(SELECT SUM(COALESCE(split_quantity, 0))
|
||||
FROM shipment_log
|
||||
WHERE target_objid = T.PROJECT_NO),
|
||||
0
|
||||
)) * COALESCE(SR.sales_unit_price, 0) AS REMAINING_AMOUNT_KRW,
|
||||
-- 잔량 계산: 수주수량 - sales_registration.sales_quantity
|
||||
COALESCE(T.QUANTITY::numeric, 0) - COALESCE(SR.sales_quantity, 0) AS REMAINING_QUANTITY,
|
||||
-- 잔량원화총액 계산: 잔량 * 판매단가
|
||||
(COALESCE(T.QUANTITY::numeric, 0) - COALESCE(SR.sales_quantity, 0)) * COALESCE(SR.sales_unit_price, 0) AS REMAINING_AMOUNT_KRW,
|
||||
COALESCE(SR.sales_currency, T.CONTRACT_CURRENCY) AS SALES_CURRENCY,
|
||||
CODE_NAME(COALESCE(SR.sales_currency, T.CONTRACT_CURRENCY)) AS SALES_CURRENCY_NAME,
|
||||
COALESCE(SR.sales_exchange_rate, T.CONTRACT_PRICE_CURRENCY::numeric, 0) AS SALES_EXCHANGE_RATE,
|
||||
@@ -942,13 +935,14 @@
|
||||
THEN '분할판매'
|
||||
ELSE ''
|
||||
END AS SALES_STATUS,
|
||||
SR.sale_no AS SALES_REG_NO,
|
||||
T.OBJID::VARCHAR AS SALE_NO,
|
||||
'ORIGINAL' AS RECORD_TYPE,
|
||||
'' AS SPLIT_LOG_ID,
|
||||
-- 거래명세서 존재 여부
|
||||
-- 거래명세서 존재 여부 (LinkedProjectObjids에 해당 프로젝트 OBJID 포함 여부)
|
||||
CASE WHEN EXISTS(
|
||||
SELECT 1 FROM NSWOS100_TBL
|
||||
WHERE OdOrderNo = T.PROJECT_NO
|
||||
SELECT 1 FROM NSWOS100_TBL
|
||||
WHERE T.OBJID::VARCHAR = ANY(STRING_TO_ARRAY(LinkedProjectObjids, ','))
|
||||
) THEN 'Y' ELSE 'N' END AS HAS_TRANSACTION_STATEMENT
|
||||
FROM PROJECT_MGMT AS T
|
||||
LEFT JOIN sales_registration SR ON T.PROJECT_NO = SR.project_no
|
||||
@@ -1346,7 +1340,18 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
AND T.CUSTOMER_OBJID = #{customer_objid}
|
||||
</if>
|
||||
<if test="serialNo != null and serialNo != ''">
|
||||
AND SR.serial_no LIKE '%' || #{serialNo} || '%'
|
||||
AND (
|
||||
EXISTS (
|
||||
SELECT 1 FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
AND UPPER(CIS.SERIAL_NO) LIKE UPPER('%' || #{serialNo} || '%')
|
||||
)
|
||||
OR SR.serial_no LIKE '%' || #{serialNo} || '%'
|
||||
)
|
||||
</if>
|
||||
<if test="poNo != null and poNo != ''">
|
||||
AND EXISTS (SELECT 1 FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID AND CM.PO_NO LIKE '%' || #{poNo} || '%')
|
||||
@@ -1550,19 +1555,17 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID) AS PAYMENT_TYPE,
|
||||
T.PART_NO AS PRODUCT_NO,
|
||||
T.PART_NAME AS PRODUCT_NAME,
|
||||
-- S/N: 해당 품목의 시리얼 번호 (여러 개일 경우 "S/N 외 N건" 형식)
|
||||
(SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 0 THEN ''
|
||||
WHEN COUNT(*) = 1 THEN MIN(CIS.SERIAL_NO)
|
||||
ELSE MIN(CIS.SERIAL_NO) || ' 외 ' || (COUNT(*) - 1)::TEXT || '건'
|
||||
END
|
||||
FROM CONTRACT_ITEM CI
|
||||
LEFT JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND CIS.SERIAL_NO IS NOT NULL) AS SERIAL_NO,
|
||||
-- S/N: CONTRACT_ITEM_SERIAL(마스터) 우선, 전체 콤마 리스트 (판매등록 폼 파싱용)
|
||||
COALESCE(
|
||||
(SELECT STRING_AGG(CIS.SERIAL_NO, ', ' ORDER BY CIS.SERIAL_NO)
|
||||
FROM CONTRACT_ITEM CI
|
||||
LEFT JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND CIS.SERIAL_NO IS NOT NULL),
|
||||
SR.serial_no
|
||||
) AS SERIAL_NO,
|
||||
COALESCE(T.QUANTITY::numeric, 0) AS ORDER_QUANTITY,
|
||||
-- 요청납기: CONTRACT_ITEM 우선, 없으면 PROJECT_MGMT, 없으면 CONTRACT_MGMT
|
||||
COALESCE(
|
||||
@@ -1648,8 +1651,8 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
CODE_NAME(CM.CONTRACT_CURRENCY) AS SALES_CURRENCY_NAME,
|
||||
COALESCE(CM.EXCHANGE_RATE::NUMERIC, 0) AS SALES_EXCHANGE_RATE,
|
||||
|
||||
-- 수주 날짜 - VARCHAR 타입이므로 그대로 사용
|
||||
CM.ORDER_DATE AS SHIPPING_DATE,
|
||||
-- 출하일 기본값: 오늘 날짜
|
||||
TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD') AS SHIPPING_DATE,
|
||||
|
||||
-- 담당자
|
||||
CM.PM_USER_ID AS MANAGER
|
||||
@@ -1662,7 +1665,6 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
CM.OBJID,
|
||||
CM.CONTRACT_CURRENCY,
|
||||
CM.EXCHANGE_RATE,
|
||||
CM.ORDER_DATE,
|
||||
CM.PM_USER_ID
|
||||
</select>
|
||||
|
||||
@@ -1696,24 +1698,35 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
CODE_NAME(CM.CONTRACT_CURRENCY) AS SALES_CURRENCY_NAME,
|
||||
COALESCE(NULLIF(CM.EXCHANGE_RATE, '')::NUMERIC, 0) AS SALES_EXCHANGE_RATE,
|
||||
|
||||
-- 수주 날짜 - VARCHAR 타입이므로 그대로 사용
|
||||
CM.ORDER_DATE AS SHIPPING_DATE,
|
||||
|
||||
-- 출하일 기본값: 오늘 날짜
|
||||
TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD') AS SHIPPING_DATE,
|
||||
|
||||
-- 담당자
|
||||
CM.PM_USER_ID AS MANAGER
|
||||
|
||||
CM.PM_USER_ID AS MANAGER,
|
||||
|
||||
-- 기존 S/N (CONTRACT_ITEM_SERIAL 마스터에서 조회)
|
||||
COALESCE((
|
||||
SELECT STRING_AGG(CIS2.SERIAL_NO, ',' ORDER BY CIS2.SEQ)
|
||||
FROM CONTRACT_ITEM CI2
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS2 ON CI2.OBJID = CIS2.ITEM_OBJID AND CIS2.STATUS = 'ACTIVE'
|
||||
WHERE CI2.CONTRACT_OBJID = PM.CONTRACT_OBJID
|
||||
AND CI2.PART_OBJID = PM.PART_OBJID
|
||||
AND CI2.STATUS = 'ACTIVE'
|
||||
), '') AS SERIAL_NO
|
||||
|
||||
FROM PROJECT_MGMT PM
|
||||
INNER JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
|
||||
LEFT JOIN CONTRACT_ITEM CI ON CM.OBJID::VARCHAR = CI.CONTRACT_OBJID AND UPPER(CI.STATUS) = 'ACTIVE'
|
||||
WHERE PM.PROJECT_NO = #{orderNo}
|
||||
GROUP BY
|
||||
GROUP BY
|
||||
CM.CONTRACT_NO,
|
||||
CM.OBJID,
|
||||
CM.CONTRACT_CURRENCY,
|
||||
CM.EXCHANGE_RATE,
|
||||
CM.ORDER_DATE,
|
||||
CM.PM_USER_ID,
|
||||
PM.QUANTITY
|
||||
PM.QUANTITY,
|
||||
PM.CONTRACT_OBJID,
|
||||
PM.PART_OBJID
|
||||
</select>
|
||||
|
||||
<!--
|
||||
@@ -1920,7 +1933,31 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
WHERE target_objid = #{projectNo}
|
||||
),
|
||||
shipping_order_status = '출하지시'
|
||||
WHERE sale_no = #{saleNo}
|
||||
<if test="managerUserId != null and managerUserId != ''">
|
||||
, manager_user_id = #{managerUserId}
|
||||
</if>
|
||||
<if test="incoterms != null and incoterms != ''">
|
||||
, incoterms = #{incoterms}
|
||||
</if>
|
||||
<if test="serialNo != null and serialNo != ''">
|
||||
, serial_no = #{serialNo}
|
||||
</if>
|
||||
<if test="shippingMethod != null and shippingMethod != ''">
|
||||
, shipping_method = #{shippingMethod}
|
||||
</if>
|
||||
<if test="shippingDate != null and shippingDate != ''">
|
||||
, shipping_date = TO_DATE(#{shippingDate}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="salesUnitPrice != null and salesUnitPrice != ''">
|
||||
, sales_unit_price = #{salesUnitPrice}::numeric
|
||||
</if>
|
||||
<if test="salesCurrency != null and salesCurrency != ''">
|
||||
, sales_currency = #{salesCurrency}
|
||||
</if>
|
||||
<if test="salesExchangeRate != null and salesExchangeRate != ''">
|
||||
, sales_exchange_rate = #{salesExchangeRate}::numeric
|
||||
</if>
|
||||
WHERE sale_no = #{saleNo}::integer
|
||||
</update>
|
||||
|
||||
<!-- PROJECT_MGMT의 OBJID 조회 (shipment_log의 target_objid로 사용) -->
|
||||
@@ -1932,19 +1969,98 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
<!-- 출하일 상세 내역 조회 (모든 분할 출하 포함) -->
|
||||
<select id="getShippingDetailList" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getShippingDetailList - shipment_log에서 모든 분할 출하 조회 */
|
||||
SELECT
|
||||
SELECT
|
||||
SL.log_id,
|
||||
COALESCE(TO_CHAR(SL.shipping_date, 'YYYY-MM-DD'), '미등록') AS shipping_date,
|
||||
COALESCE(SL.split_quantity, 0) AS shipping_quantity,
|
||||
COALESCE(SL.shipping_status, '미등록') AS shipping_order_status,
|
||||
COALESCE(SL.serial_no, '-') AS serial_no,
|
||||
COALESCE((
|
||||
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
|
||||
FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
|
||||
JOIN PROJECT_MGMT PM ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID AND PM.PART_OBJID = CI.PART_OBJID
|
||||
WHERE PM.PROJECT_NO = SL.target_objid AND CI.STATUS = 'ACTIVE'
|
||||
), '-') AS serial_no,
|
||||
SL.target_objid AS project_no,
|
||||
'분할 출하 ' || SL.log_id AS source,
|
||||
TO_CHAR(SL.reg_date, 'YYYY-MM-DD HH24:MI:SS') AS reg_date
|
||||
FROM shipment_log SL
|
||||
FROM shipment_log SL
|
||||
WHERE SL.target_objid = #{projectNo}
|
||||
ORDER BY SL.shipping_date DESC, SL.log_id DESC
|
||||
</select>
|
||||
|
||||
|
||||
<!-- shipment_log 단건 조회 (수정 팝업용) -->
|
||||
<select id="getShipmentLogById" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getShipmentLogById - shipment_log 단건 조회 */
|
||||
SELECT
|
||||
SL.log_id,
|
||||
SL.target_objid,
|
||||
COALESCE(TO_CHAR(SL.shipping_date, 'YYYY-MM-DD'), '') AS SHIPPING_DATE,
|
||||
COALESCE(SL.split_quantity, 0) AS SALES_QUANTITY,
|
||||
COALESCE(SL.shipping_status, '') AS SHIPPING_ORDER_STATUS,
|
||||
COALESCE(SL.shipping_method, '') AS SHIPPING_METHOD,
|
||||
COALESCE((
|
||||
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
|
||||
FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
|
||||
JOIN PROJECT_MGMT PM ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID AND PM.PART_OBJID = CI.PART_OBJID
|
||||
WHERE PM.PROJECT_NO = SL.target_objid AND CI.STATUS = 'ACTIVE'
|
||||
), '') AS SERIAL_NO,
|
||||
COALESCE(SL.sales_unit_price, 0) AS SALES_UNIT_PRICE,
|
||||
COALESCE(SL.sales_supply_price, 0) AS SALES_SUPPLY_PRICE,
|
||||
COALESCE(SL.sales_vat, 0) AS SALES_VAT,
|
||||
COALESCE(SL.sales_total_amount, 0) AS SALES_TOTAL_AMOUNT,
|
||||
COALESCE(SL.sales_currency, '') AS SALES_CURRENCY,
|
||||
COALESCE(SL.sales_exchange_rate, 0) AS SALES_EXCHANGE_RATE,
|
||||
COALESCE(SL.manager_user_id, '') AS MANAGER,
|
||||
COALESCE(SL.incoterms, '') AS INCOTERMS,
|
||||
COALESCE(SL.original_quantity, 0) AS ORDER_QUANTITY,
|
||||
COALESCE(SL.remaining_quantity, 0) AS REMAINING_QUANTITY
|
||||
FROM shipment_log SL
|
||||
WHERE SL.log_id = #{logId}::integer
|
||||
</select>
|
||||
|
||||
<!-- shipment_log 수정 -->
|
||||
<update id="updateShipmentLog" parameterType="map">
|
||||
/* salesNcollectMgmt.updateShipmentLog - shipment_log 수정 */
|
||||
UPDATE shipment_log SET
|
||||
split_quantity = #{salesQuantity}::integer,
|
||||
shipping_status = #{shippingOrderStatus}
|
||||
<if test="shippingDate != null and shippingDate != ''">
|
||||
, shipping_date = TO_DATE(#{shippingDate}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="shippingMethod != null and shippingMethod != ''">
|
||||
, shipping_method = #{shippingMethod}
|
||||
</if>
|
||||
<if test="serialNo != null and serialNo != ''">
|
||||
, serial_no = #{serialNo}
|
||||
</if>
|
||||
<if test="salesUnitPrice != null and salesUnitPrice != ''">
|
||||
, sales_unit_price = #{salesUnitPrice}::numeric
|
||||
</if>
|
||||
<if test="salesSupplyPrice != null and salesSupplyPrice != ''">
|
||||
, sales_supply_price = #{salesSupplyPrice}::numeric
|
||||
</if>
|
||||
<if test="salesVat != null and salesVat != ''">
|
||||
, sales_vat = #{salesVat}::numeric
|
||||
</if>
|
||||
<if test="salesTotalAmount != null and salesTotalAmount != ''">
|
||||
, sales_total_amount = #{salesTotalAmount}::numeric
|
||||
</if>
|
||||
<if test="salesCurrency != null and salesCurrency != ''">
|
||||
, sales_currency = #{salesCurrency}
|
||||
</if>
|
||||
<if test="salesExchangeRate != null and salesExchangeRate != ''">
|
||||
, sales_exchange_rate = #{salesExchangeRate}::numeric
|
||||
</if>
|
||||
<if test="managerUserId != null and managerUserId != ''">
|
||||
, manager_user_id = #{managerUserId}
|
||||
</if>
|
||||
<if test="incoterms != null and incoterms != ''">
|
||||
, incoterms = #{incoterms}
|
||||
</if>
|
||||
WHERE log_id = #{logId}::integer
|
||||
</update>
|
||||
|
||||
<!-- 거래명세서 - 고객 정보 조회 -->
|
||||
<select id="getCustomerInfoByProjectNo" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getCustomerInfoByProjectNo - 프로젝트 번호로 고객 정보 조회 */
|
||||
@@ -1976,7 +2092,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
WHERE PM.PROJECT_NO = #{projectNo}
|
||||
</select>
|
||||
|
||||
<!-- 거래명세서 저장 - NSWOS100_TBL 테이블 사용 -->
|
||||
<!-- 거래명세서 저장 - NSWOS100_TBL 테이블 사용 (ON CONFLICT DO UPDATE) -->
|
||||
<insert id="saveTransactionStatement" parameterType="map">
|
||||
/* salesNcollectMgmt.saveTransactionStatement - 거래명세서 저장 */
|
||||
INSERT INTO NSWOS100_TBL (
|
||||
@@ -1995,6 +2111,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
,IsQty /* 납품수량 */
|
||||
,IsPrice /* 납품단가 */
|
||||
,IsAmount /* 납품금액 */
|
||||
,LinkedProjectObjids /* 연결된 프로젝트 OBJID 목록 */
|
||||
) VALUES (
|
||||
#{suVndCd} /* 업체코드 */
|
||||
,#{issueDt} /* 작성일자 */
|
||||
@@ -2011,6 +2128,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
,COALESCE(#{isQty}, 0)::integer /* 납품수량 */
|
||||
,COALESCE(#{isPrice}, 0)::numeric /* 납품단가 */
|
||||
,COALESCE(#{isAmount}, 0)::numeric /* 납품금액 */
|
||||
,#{linkedProjectObjids} /* 연결된 프로젝트 OBJID 목록 */
|
||||
) ON CONFLICT (SuVndCd, IssueDt, IssueNo, IsNo) DO
|
||||
UPDATE SET
|
||||
ProdCd = COALESCE(#{prodCd}, '')
|
||||
@@ -2024,6 +2142,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
,IsQty = COALESCE(#{isQty}, 0)::integer
|
||||
,IsPrice = COALESCE(#{isPrice}, 0)::numeric
|
||||
,IsAmount = COALESCE(#{isAmount}, 0)::numeric
|
||||
,LinkedProjectObjids = #{linkedProjectObjids}
|
||||
</insert>
|
||||
|
||||
<!-- 거래명세서 번호 생성 -->
|
||||
@@ -2051,7 +2170,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
|
||||
<select id="getSavedTransactionStatement" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getSavedTransactionStatement - 저장된 거래명세서 조회 */
|
||||
SELECT
|
||||
SELECT
|
||||
SuVndCd,
|
||||
IssueDt,
|
||||
IssueNo,
|
||||
@@ -2066,9 +2185,10 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
IsDt,
|
||||
IsQty,
|
||||
IsPrice,
|
||||
IsAmount
|
||||
IsAmount,
|
||||
LinkedProjectObjids
|
||||
FROM NSWOS100_TBL
|
||||
WHERE OdOrderNo = #{projectNo}
|
||||
WHERE #{projectObjid} = ANY(STRING_TO_ARRAY(LinkedProjectObjids, ','))
|
||||
ORDER BY IsNo
|
||||
</select>
|
||||
|
||||
@@ -2142,6 +2262,102 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
LOADING_DATE = #{loadingDate}
|
||||
WHERE OBJID::VARCHAR = #{OBJID}
|
||||
</update>
|
||||
|
||||
|
||||
<!--
|
||||
/**
|
||||
* 매출마감 전표연동용 데이터 조회
|
||||
* OBJID 리스트로 전표 생성에 필요한 모든 정보를 일괄 조회한다.
|
||||
* @since 2026.02.24
|
||||
* @author system
|
||||
* @version 1.0
|
||||
**/
|
||||
-->
|
||||
<select id="getErpAccountCode" parameterType="map" resultType="com.pms.common.UpperKeyMap">
|
||||
/* salesNcollectMgmt.getErpAccountCode - ERP 계정과목코드 조회 */
|
||||
SELECT acct_cd AS ACCT_CD, acct_nm AS ACCT_NM
|
||||
FROM erp_acct_code
|
||||
WHERE co_cd = #{coCd}
|
||||
AND acct_nm = #{acctNm}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="getSlipDataForDeadline" parameterType="map" resultType="com.pms.common.UpperKeyMap">
|
||||
/* salesNcollectMgmt.getSlipDataForDeadline - 매출마감 전표연동용 데이터 조회 */
|
||||
SELECT
|
||||
PM.OBJID,
|
||||
PM.PROJECT_NO,
|
||||
PM.AREA_CD,
|
||||
PM.CUSTOMER_OBJID,
|
||||
PM.PART_NO,
|
||||
PM.PART_NAME,
|
||||
COALESCE(PM.TAX_TYPE, '') AS TAX_TYPE,
|
||||
COALESCE(PM.TAX_INVOICE_DATE, '') AS TAX_INVOICE_DATE,
|
||||
COALESCE(PM.EXPORT_DECL_NO, '') AS EXPORT_DECL_NO,
|
||||
COALESCE(PM.LOADING_DATE, '') AS LOADING_DATE,
|
||||
COALESCE(PM.SALES_STATUS, '') AS SALES_STATUS,
|
||||
/* 거래처 정보: ERP 연동 거래처(C_ 접두어)에서 client_cd 조회 */
|
||||
CASE WHEN PM.CUSTOMER_OBJID LIKE 'C_%' THEN
|
||||
(SELECT C.CLIENT_CD FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = PM.CUSTOMER_OBJID)
|
||||
ELSE NULL END AS ERP_CLIENT_CD,
|
||||
CASE WHEN PM.CUSTOMER_OBJID LIKE 'C_%' THEN
|
||||
(SELECT C.CLIENT_NM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = PM.CUSTOMER_OBJID)
|
||||
ELSE
|
||||
(SELECT S.SUPPLY_NAME FROM SUPPLY_MNG S WHERE S.OBJID::VARCHAR = PM.CUSTOMER_OBJID::VARCHAR)
|
||||
END AS CUSTOMER_NAME,
|
||||
CASE WHEN PM.CUSTOMER_OBJID LIKE 'C_%' THEN
|
||||
(SELECT C.BUS_REG_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = PM.CUSTOMER_OBJID)
|
||||
ELSE NULL END AS BUS_REG_NO,
|
||||
/* 판매 금액 정보 */
|
||||
COALESCE(SR.SALES_SUPPLY_PRICE, 0) AS SALES_SUPPLY_PRICE,
|
||||
COALESCE(SR.SALES_VAT, 0) AS SALES_VAT,
|
||||
COALESCE(SR.SALES_TOTAL_AMOUNT, 0) AS SALES_TOTAL_AMOUNT,
|
||||
/* 환종/환율 (해외) */
|
||||
COALESCE(SR.SALES_CURRENCY, PM.CONTRACT_CURRENCY) AS SALES_CURRENCY,
|
||||
COALESCE(SR.SALES_EXCHANGE_RATE, 0) AS SALES_EXCHANGE_RATE,
|
||||
/* 외화 총액 계산: 원화총액 / 환율 (환율이 0이 아닐 때) */
|
||||
CASE WHEN COALESCE(SR.SALES_EXCHANGE_RATE, 0) > 0 THEN
|
||||
ROUND(COALESCE(SR.SALES_TOTAL_AMOUNT, 0)::NUMERIC / SR.SALES_EXCHANGE_RATE::NUMERIC, 2)
|
||||
ELSE 0 END AS FOREIGN_AMOUNT
|
||||
FROM PROJECT_MGMT PM
|
||||
LEFT JOIN SALES_REGISTRATION SR ON PM.PROJECT_NO = SR.PROJECT_NO
|
||||
WHERE PM.OBJID::VARCHAR = #{OBJID}
|
||||
</select>
|
||||
|
||||
<!--
|
||||
/**
|
||||
* 매출마감 전표번호 시퀀스 조회
|
||||
* 동일 일자의 최대 작성번호를 조회하여 다음 번호를 부여한다.
|
||||
* @since 2026.02.24
|
||||
* @author system
|
||||
* @version 1.0
|
||||
**/
|
||||
-->
|
||||
<select id="getNextSlipMenuSq" parameterType="map" resultType="int">
|
||||
/* salesNcollectMgmt.getNextSlipMenuSq - 다음 전표 작성번호 조회 */
|
||||
SELECT COALESCE(MAX(SLIP_MENU_SQ), 0) + 1
|
||||
FROM PROJECT_MGMT
|
||||
WHERE SALES_SLIP_DATE = #{slipDate}
|
||||
AND SALES_SLIP_MENU_SQ IS NOT NULL
|
||||
</select>
|
||||
|
||||
<!--
|
||||
/**
|
||||
* 매출마감 완료 후 전표 정보 저장
|
||||
* @since 2026.02.24
|
||||
* @author system
|
||||
* @version 1.0
|
||||
**/
|
||||
-->
|
||||
<update id="updateSlipInfo" parameterType="map">
|
||||
/* salesNcollectMgmt.updateSlipInfo - 전표 연동 정보 저장 */
|
||||
UPDATE PROJECT_MGMT
|
||||
SET
|
||||
SALES_STATUS = '완료',
|
||||
SALES_DEADLINE_DATE = #{deadlineDate},
|
||||
SALES_SLIP_DATE = #{slipDate},
|
||||
SALES_SLIP_MENU_SQ = #{slipMenuSq}
|
||||
WHERE OBJID::VARCHAR = #{OBJID}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
|
||||
@@ -467,7 +467,8 @@ var columns = [
|
||||
},
|
||||
cellClick:function(e, cell){
|
||||
var serialNo = fnc_checkNull(cell.getData().SERIAL_NO);
|
||||
fn_showSerialNoPopup(serialNo);
|
||||
var contractObjId = fnc_checkNull(cell.getData().OBJID);
|
||||
fn_showSerialNoPopup(serialNo, contractObjId);
|
||||
}
|
||||
},
|
||||
// 17. 품번
|
||||
@@ -784,29 +785,49 @@ function fn_openEstimateTemplate(objId, templateType){
|
||||
}
|
||||
|
||||
// S/N 목록 팝업 표시
|
||||
function fn_showSerialNoPopup(serialNoString){
|
||||
function fn_showSerialNoPopup(serialNoString, contractObjId){
|
||||
if(!serialNoString || serialNoString === ''){
|
||||
Swal.fire("S/N 정보가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 쉼표로 구분된 S/N을 배열로 변환
|
||||
var serialNumbers = serialNoString.split(',').map(function(sn){ return sn.trim(); });
|
||||
|
||||
// HTML 리스트 생성
|
||||
// "외 N건" 형식이면 서버에서 전체 S/N 조회
|
||||
if(serialNoString.indexOf('외') > -1 && serialNoString.indexOf('건') > -1 && contractObjId){
|
||||
$.ajax({
|
||||
url: '/contractMgmt/getAllSerialNumbers.do',
|
||||
type: 'POST',
|
||||
data: { contractObjId: contractObjId },
|
||||
dataType: 'json',
|
||||
success: function(response){
|
||||
if(response.result === 'success' && response.serialNumbers && response.serialNumbers.length > 0){
|
||||
fn_displaySerialNoList(response.serialNumbers);
|
||||
} else {
|
||||
fn_displaySerialNoList([serialNoString]);
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
fn_displaySerialNoList([serialNoString]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var serialNumbers = serialNoString.split(',').map(function(sn){ return sn.trim(); }).filter(function(sn){ return sn !== ''; });
|
||||
fn_displaySerialNoList(serialNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
// S/N 리스트 팝업 표시 (공통)
|
||||
function fn_displaySerialNoList(serialNumbers){
|
||||
var listHtml = '<div style="text-align: left; max-height: 400px; overflow-y: auto;">';
|
||||
listHtml += '<ol style="padding-left: 20px; margin: 10px 0;">';
|
||||
serialNumbers.forEach(function(sn, index){
|
||||
serialNumbers.forEach(function(sn){
|
||||
listHtml += '<li style="padding: 5px 0; font-size: 14px;">' + sn + '</li>';
|
||||
});
|
||||
listHtml += '</ol>';
|
||||
listHtml += '</div>';
|
||||
|
||||
// SweetAlert2로 팝업 표시
|
||||
Swal.fire({
|
||||
title: 'S/N 목록',
|
||||
html: listHtml,
|
||||
icon: 'info',
|
||||
width: 500,
|
||||
confirmButtonText: '확인',
|
||||
confirmButtonColor: '#3085d6'
|
||||
|
||||
@@ -288,6 +288,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 결재여부 체크박스 토글 (단일 선택)
|
||||
function fn_toggleApprovalRequired(clicked) {
|
||||
$("input[name='approval_required_chk']").prop("checked", false);
|
||||
$(clicked).prop("checked", true);
|
||||
$("#approval_required").val($(clicked).val());
|
||||
}
|
||||
|
||||
function fn_save() {
|
||||
if (fnc_valitate("form1")) {
|
||||
// 품목 유효성 검사
|
||||
@@ -1990,6 +1997,25 @@
|
||||
<input type="text" name="exchange_rate" id="exchange_rate" reqTitle="환율" value="${info.EXCHANGE_RATE}" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 세번째 행: 결재여부 -->
|
||||
<tr>
|
||||
<td class="input_title"><label>결재여부 <span style="color:red;">*</span></label></td>
|
||||
<td colspan="7">
|
||||
<label style="margin-right:15px; cursor:pointer;">
|
||||
<input type="checkbox" name="approval_required_chk" value="Y"
|
||||
${info.APPROVAL_REQUIRED eq 'Y' ? 'checked' : ''}
|
||||
onchange="fn_toggleApprovalRequired(this)" /> 필요
|
||||
</label>
|
||||
<label style="cursor:pointer;">
|
||||
<input type="checkbox" name="approval_required_chk" value="N"
|
||||
${info.APPROVAL_REQUIRED ne 'Y' ? 'checked' : ''}
|
||||
onchange="fn_toggleApprovalRequired(this)" /> 불필요
|
||||
</label>
|
||||
<input type="hidden" name="approval_required" id="approval_required"
|
||||
value="${info.APPROVAL_REQUIRED ne 'Y' ? 'N' : 'Y'}" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -355,7 +355,8 @@ var columns = [
|
||||
},
|
||||
cellClick:function(e, cell){
|
||||
var serialNo = fnc_checkNull(cell.getData().SERIAL_NO);
|
||||
fn_showSerialNoPopup(serialNo);
|
||||
var contractObjId = fnc_checkNull(cell.getData().OBJID);
|
||||
fn_showSerialNoPopup(serialNo, contractObjId);
|
||||
}
|
||||
},
|
||||
// 21. 품번
|
||||
@@ -657,29 +658,49 @@ function fn_openEstimateTemplate(objId, templateType){
|
||||
}
|
||||
|
||||
// S/N 목록 팝업 표시
|
||||
function fn_showSerialNoPopup(serialNoString){
|
||||
function fn_showSerialNoPopup(serialNoString, contractObjId){
|
||||
if(!serialNoString || serialNoString === ''){
|
||||
Swal.fire("S/N 정보가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 쉼표로 구분된 S/N을 배열로 변환
|
||||
var serialNumbers = serialNoString.split(',').map(function(sn){ return sn.trim(); });
|
||||
|
||||
// HTML 리스트 생성
|
||||
// "외 N건" 형식이면 서버에서 전체 S/N 조회
|
||||
if(serialNoString.indexOf('외') > -1 && serialNoString.indexOf('건') > -1 && contractObjId){
|
||||
$.ajax({
|
||||
url: '/contractMgmt/getAllSerialNumbers.do',
|
||||
type: 'POST',
|
||||
data: { contractObjId: contractObjId },
|
||||
dataType: 'json',
|
||||
success: function(response){
|
||||
if(response.result === 'success' && response.serialNumbers && response.serialNumbers.length > 0){
|
||||
fn_displaySerialNoList(response.serialNumbers);
|
||||
} else {
|
||||
fn_displaySerialNoList([serialNoString]);
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
fn_displaySerialNoList([serialNoString]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var serialNumbers = serialNoString.split(',').map(function(sn){ return sn.trim(); }).filter(function(sn){ return sn !== ''; });
|
||||
fn_displaySerialNoList(serialNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
// S/N 리스트 팝업 표시 (공통)
|
||||
function fn_displaySerialNoList(serialNumbers){
|
||||
var listHtml = '<div style="text-align: left; max-height: 400px; overflow-y: auto;">';
|
||||
listHtml += '<ol style="padding-left: 20px; margin: 10px 0;">';
|
||||
serialNumbers.forEach(function(sn, index){
|
||||
serialNumbers.forEach(function(sn){
|
||||
listHtml += '<li style="padding: 5px 0; font-size: 14px;">' + sn + '</li>';
|
||||
});
|
||||
listHtml += '</ol>';
|
||||
listHtml += '</div>';
|
||||
|
||||
// SweetAlert2로 팝업 표시
|
||||
Swal.fire({
|
||||
title: 'S/N 목록',
|
||||
html: listHtml,
|
||||
icon: 'info',
|
||||
width: 500,
|
||||
confirmButtonText: '확인',
|
||||
confirmButtonColor: '#3085d6'
|
||||
|
||||
@@ -957,6 +957,9 @@ function fn_initGrid() {
|
||||
function fn_preprocessBomData(dataList) {
|
||||
if(!dataList || dataList.length === 0) return dataList;
|
||||
|
||||
// 레벨별 항목수량 추적 (제작수량 누적 곱 계산용)
|
||||
var parentItemQtyByLevel = {};
|
||||
|
||||
dataList.forEach(function(row) {
|
||||
// 필드명 정규화 (소문자 → 대문자 복사, 기존 대문자 유지)
|
||||
if(row.part_unit_qty !== undefined && row.PART_UNIT_QTY === undefined) {
|
||||
@@ -985,13 +988,27 @@ function fn_initGrid() {
|
||||
|
||||
console.log("전처리 - PART_NO:", row.PART_NO, "소재품번:", row.RAW_MATERIAL_NO, "소재소요량(DB):", savedRequiredQty, "소재소요량(최종):", row.REQUIRED_QTY);
|
||||
|
||||
// 제작수량: 저장된 값이 있으면 유지, 없으면 항목수량 × 총생산수량으로 자동계산
|
||||
// 제작수량: 상위 항목수량을 누적 곱하여 계산
|
||||
var level = parseInt(row.LEVEL) || 1;
|
||||
var itemQty = parseFloat(row.ITEM_QTY || row.item_qty) || 0;
|
||||
|
||||
// 현재 레벨의 항목수량 저장 (하위 레벨 계산에 사용)
|
||||
parentItemQtyByLevel[level] = itemQty;
|
||||
// 현재 레벨보다 깊은 레벨 데이터 제거 (형제 노드 전환 시 오염 방지)
|
||||
for(var l = level + 1; l <= _maxLevel; l++) {
|
||||
delete parentItemQtyByLevel[l];
|
||||
}
|
||||
|
||||
var savedProdQty = parseFloat(row.PRODUCTION_QTY) || 0;
|
||||
if(savedProdQty > 0) {
|
||||
row.PRODUCTION_QTY = savedProdQty;
|
||||
} else {
|
||||
var itemQty = parseFloat(row.ITEM_QTY || row.item_qty) || 0;
|
||||
row.PRODUCTION_QTY = itemQty * totalProductionQty;
|
||||
// 최상위(1)부터 현재 레벨까지 항목수량 누적 곱 × 총생산수량
|
||||
var cumulativeItemQty = 1;
|
||||
for(var l = 1; l <= level; l++) {
|
||||
cumulativeItemQty *= (parentItemQtyByLevel[l] || 1);
|
||||
}
|
||||
row.PRODUCTION_QTY = cumulativeItemQty * totalProductionQty;
|
||||
}
|
||||
|
||||
// 소재발주수량: 저장된 값이 있으면 유지, 없으면 계산
|
||||
|
||||
@@ -144,26 +144,15 @@ $(document).ready(function(){
|
||||
fn_search();
|
||||
});
|
||||
|
||||
// 프로젝트별 파트 목록 캐시
|
||||
var _PART_LIST_CACHE = {};
|
||||
|
||||
// 프로젝트번호로 MBOM 파트 목록 조회
|
||||
// 프로젝트번호로 MBOM 파트 목록 조회 (미선택 시 전체 조회)
|
||||
function fn_getPartListByProject(projectNo) {
|
||||
if (!projectNo) return [{"CODE": "", "NAME": "선택"}];
|
||||
var param = {"sqlId": "common.getMbomPartListByProjectNo"};
|
||||
if (projectNo) param.PROJECT_NO = projectNo;
|
||||
|
||||
// 캐시에 있으면 캐시에서 반환
|
||||
if (_PART_LIST_CACHE[projectNo]) {
|
||||
return _PART_LIST_CACHE[projectNo];
|
||||
}
|
||||
|
||||
// 서버에서 조회
|
||||
var partList = [{"CODE": "", "NAME": "선택"}].concat(
|
||||
fnc_getJsonAllDataListBySqlId({"sqlId": "common.getMbomPartListByProjectNo", "PROJECT_NO": projectNo})
|
||||
fnc_getJsonAllDataListBySqlId(param)
|
||||
);
|
||||
|
||||
// 캐시에 저장
|
||||
_PART_LIST_CACHE[projectNo] = partList;
|
||||
|
||||
return partList;
|
||||
}
|
||||
|
||||
@@ -207,30 +196,32 @@ function fn_select2Editor(cell, onRendered, success, cancel, editorParams) {
|
||||
$(select).select2("open");
|
||||
});
|
||||
|
||||
var isCleared = false;
|
||||
var isCompleted = false;
|
||||
|
||||
$(select).on("select2:select", function(e) {
|
||||
if(isCompleted) return;
|
||||
isCompleted = true;
|
||||
var selectedVal = $(select).val() || "";
|
||||
if(typeof editorParams.onSelect === "function") {
|
||||
editorParams.onSelect(cell, selectedVal);
|
||||
}
|
||||
try { $(select).select2("destroy"); } catch(e) {}
|
||||
success(selectedVal);
|
||||
});
|
||||
|
||||
$(select).on("select2:clear", function(e) {
|
||||
isCleared = true;
|
||||
if(typeof editorParams.onSelect === "function") {
|
||||
editorParams.onSelect(cell, "");
|
||||
}
|
||||
if(isCompleted) return;
|
||||
isCompleted = true;
|
||||
var $sel = $(select);
|
||||
setTimeout(function() {
|
||||
$(select).select2("close");
|
||||
try { $sel.select2("destroy"); } catch(e) {}
|
||||
success("");
|
||||
}, 0);
|
||||
}, 50);
|
||||
});
|
||||
|
||||
$(select).on("select2:close", function() {
|
||||
if(isCleared) return;
|
||||
success($(select).val() || "");
|
||||
if(isCompleted) return;
|
||||
isCompleted = true;
|
||||
var val = $(select).val() || "";
|
||||
try { $(select).select2("destroy"); } catch(e) {}
|
||||
success(val);
|
||||
});
|
||||
|
||||
return container;
|
||||
@@ -270,21 +261,7 @@ function fn_search(){
|
||||
editor: fn_select2Editor,
|
||||
editorParams: {
|
||||
valueId: "CODE", labelId: "NAME", values: _PROJECT_LIST,
|
||||
placeholder: "프로젝트 검색...",
|
||||
onSelect: function(cell, selectedValue) {
|
||||
var productName = "";
|
||||
for(var i = 0; i < _PROJECT_LIST.length; i++) {
|
||||
if(_PROJECT_LIST[i].CODE == selectedValue) {
|
||||
productName = _PROJECT_LIST[i].PRODUCT_NAME || "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(selectedValue) fn_getPartListByProject(selectedValue);
|
||||
cell.getRow().update({
|
||||
"PART_OBJID": "", "PART_NO": "", "PART_NAME": "",
|
||||
"PRODUCT_NAME": productName
|
||||
});
|
||||
}
|
||||
placeholder: "프로젝트 검색..."
|
||||
},
|
||||
formatter: function(cell) {
|
||||
return fnc_customSelectFormatter(cell, {valueId:"CODE", labelId:"NAME", values:_PROJECT_LIST});
|
||||
@@ -412,11 +389,28 @@ function fn_search(){
|
||||
var row = cell.getRow();
|
||||
var field = cell.getField();
|
||||
|
||||
// 프로젝트 변경 시 제품구분 설정 + 파트 초기화
|
||||
if (field === 'PROJECT_OBJID') {
|
||||
var projectObjid = cell.getValue() || "";
|
||||
var productName = "";
|
||||
for(var i = 0; i < _PROJECT_LIST.length; i++) {
|
||||
if(_PROJECT_LIST[i].CODE == projectObjid) {
|
||||
productName = _PROJECT_LIST[i].PRODUCT_NAME || "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
fn_getPartListByProject(projectObjid);
|
||||
row.update({
|
||||
"PART_OBJID": "", "PART_NO": "", "PART_NAME": "",
|
||||
"PRODUCT_NAME": productName
|
||||
});
|
||||
}
|
||||
|
||||
// 파트 선택 시 품번/품명 자동 설정
|
||||
if (field === 'PART_OBJID') {
|
||||
var partObjid = cell.getValue();
|
||||
var projectObjid = row.getData().PROJECT_OBJID;
|
||||
if (partObjid && projectObjid) {
|
||||
if (partObjid) {
|
||||
var partList = fn_getPartListByProject(projectObjid);
|
||||
for (var i = 0; i < partList.length; i++) {
|
||||
if (partList[i].CODE == partObjid) {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
background: #f9f9f9;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
width: 70px;
|
||||
}
|
||||
.item-table {
|
||||
width: 100%;
|
||||
|
||||
@@ -78,10 +78,10 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
// 선택된 OBJID 목록
|
||||
var objIdList = [];
|
||||
// 선택된 LOG_ID 목록
|
||||
var logIdList = [];
|
||||
for(var i = 0; i < targetObj.length; i++){
|
||||
objIdList.push(fnc_checkNull(targetObj[i].OBJID));
|
||||
logIdList.push(fnc_checkNull(targetObj[i].LOG_ID));
|
||||
}
|
||||
|
||||
// 단건 선택 시 기존 마감정보 불러오기
|
||||
@@ -164,7 +164,7 @@
|
||||
url: "/revenueMgmt/saveDeadlineInfo.do",
|
||||
type: "POST",
|
||||
data: {
|
||||
"objIdList": objIdList.join(','),
|
||||
"logIdList": logIdList.join(','),
|
||||
"taxType": formData.taxType,
|
||||
"taxInvoiceDate": formData.taxInvoiceDate,
|
||||
"exportDeclNo": formData.exportDeclNo,
|
||||
@@ -286,17 +286,17 @@
|
||||
}).then(function(result) {
|
||||
if (result.isConfirmed) {
|
||||
var deadlineDate = result.value;
|
||||
var objIdList = [];
|
||||
var logIdList = [];
|
||||
|
||||
for(var i = 0; i < targetObj.length; i++){
|
||||
objIdList.push(fnc_checkNull(targetObj[i].OBJID));
|
||||
logIdList.push(fnc_checkNull(targetObj[i].LOG_ID));
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/salesNcollectMgmt/salesDeadlineConfirm.do",
|
||||
type: "POST",
|
||||
data: {
|
||||
"objIdList": objIdList.join(','),
|
||||
"logIdList": logIdList.join(','),
|
||||
"deadlineDate": deadlineDate
|
||||
},
|
||||
dataType: "json",
|
||||
@@ -332,7 +332,13 @@ var columns = [
|
||||
// 컬럼 순서: 프로젝트번호, 주문유형, 매출마감, 발주일, 발주번호, 고객사, 제품구분, 품명, 수량, 단가, 공급가액, 부가세, 총액, 원화총액, 출하일, 국내/해외, 환종, 환율, S/N, 품번
|
||||
{formatter:"rowSelection", titleFormatter:"rowSelection", hozAlign:"center", headerSort:false, width:40, frozen:true},
|
||||
// 1. 프로젝트번호
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '130', title : '프로젝트번호', field : 'PROJECT_NO', frozen : true},
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '130', title : '프로젝트번호', field : 'PROJECT_NO', frozen : true,
|
||||
formatter: fnc_createGridAnchorTag,
|
||||
cellClick: function(e, cell){
|
||||
var orderNo = cell.getData().PROJECT_NO;
|
||||
fn_openSaleRegPopup(orderNo, "detail");
|
||||
}
|
||||
},
|
||||
// 2. 주문유형
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '주문유형', field : 'ORDER_TYPE'},
|
||||
// 3. 매출마감
|
||||
@@ -605,6 +611,13 @@ function fn_excel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function fn_openSaleRegPopup(orderNo, saleNo){
|
||||
var popup_width = 850;
|
||||
var popup_height = 520;
|
||||
var url = "/salesMgmt/salesRegForm.do?orderNo=" + encodeURIComponent(orderNo) + "&saleNo=" + (saleNo ? encodeURIComponent(saleNo) : "");
|
||||
fn_centerPopup(popup_width, popup_height, url);
|
||||
}
|
||||
|
||||
function fn_FileRegist(objId, docType, docTypeName){
|
||||
var popup_width = 800;
|
||||
var popup_height = 680;
|
||||
@@ -624,7 +637,7 @@ function fn_FileRegist(objId, docType, docTypeName){
|
||||
|
||||
<form name="form1" id="form1" method="post">
|
||||
<input type="hidden" name="actionType" id="actionType">
|
||||
<input type="hidden" name="shippingDateRequired" value="Y"> <!-- 출하일 필수 조건 -->
|
||||
<input type="hidden" name="revenueMode" value="Y"> <!-- 매출관리 모드: shipment_log 기반 조회 -->
|
||||
<!-- 과세구분 코드 - 매출마감용 (과세매출/수출만 표시) -->
|
||||
<select id="hiddenTaxTypeList" style="display:none;">
|
||||
<option value="">선택</option>
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
|
||||
function fn_openSaleRegPopup(orderNo, saleNo){
|
||||
var popup_width = 850;
|
||||
var popup_height = 400;
|
||||
var popup_height = 520;
|
||||
// 한글 프로젝트 번호 인코딩 처리
|
||||
var url = "/salesMgmt/salesRegForm.do?orderNo=" + encodeURIComponent(orderNo) + "&saleNo=" + (saleNo ? encodeURIComponent(saleNo) : "");
|
||||
fn_centerPopup(popup_width, popup_height, url);
|
||||
@@ -302,14 +302,18 @@ var columns = [
|
||||
// 5. 요청납기
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : '요청납기', field : 'REQUEST_DATE'},
|
||||
// 6. 출하일
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : '출하일', field : 'SHIPPING_DATE_WITH_COUNT',
|
||||
{headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '출하일', field : 'SHIPPING_DATE_WITH_COUNT',
|
||||
formatter: function(cell) {
|
||||
var value = cell.getValue();
|
||||
var displayText = '';
|
||||
if(!value || value.trim() === '') {
|
||||
var data = cell.getRow().getData();
|
||||
return data.SHIPPING_DATE || '';
|
||||
displayText = data.SHIPPING_DATE || '';
|
||||
} else {
|
||||
displayText = value;
|
||||
}
|
||||
return value;
|
||||
if(!displayText) return '';
|
||||
return '<a href="javascript:void(0);" style="color:#2196F3;">' + displayText + '</a>';
|
||||
},
|
||||
cellClick: function(e, cell) {
|
||||
var projectNo = cell.getRow().getData().PROJECT_NO;
|
||||
@@ -620,19 +624,21 @@ function fn_openTransactionStatementPopup(projectNo, projectObjid, hasStatement)
|
||||
}
|
||||
|
||||
function fn_openShippingDetail(projectNo) {
|
||||
console.log("=== fn_openShippingDetail 호출 ===");
|
||||
console.log("전달받은 projectNo:", projectNo);
|
||||
console.log("projectNo 타입:", typeof projectNo);
|
||||
|
||||
if(!projectNo) {
|
||||
alert("프로젝트 번호가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var url = "/salesMgmt/shippingDetailPopup.do?projectNo=" + encodeURIComponent(projectNo);
|
||||
console.log("팝업 URL:", url);
|
||||
|
||||
window.open(url, "shippingDetailPopup", "width=800,height=600,scrollbars=yes,resizable=yes");
|
||||
var detailPopup = window.open(url, "shippingDetailPopup", "width=800,height=600,scrollbars=yes,resizable=yes");
|
||||
|
||||
// 팝업 닫힐 때 목록 새로고침
|
||||
var checkPopup = setInterval(function() {
|
||||
if(detailPopup.closed) {
|
||||
clearInterval(checkPopup);
|
||||
fn_search();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// 분할출하 함수 - 선택한 항목을 동일 프로젝트번호로 분할출하
|
||||
@@ -702,13 +708,8 @@ function fn_bulkRegister(){
|
||||
}
|
||||
}
|
||||
|
||||
if(selectedRow.SALES_REG_NO) {
|
||||
// 기존 판매등록 수정 모드
|
||||
fn_openSaleRegPopup(selectedRow.PROJECT_NO, selectedRow.SALES_REG_NO);
|
||||
} else {
|
||||
// 신규 판매등록
|
||||
fn_openSaleRegPopupWithData(selectedRow);
|
||||
}
|
||||
// 항상 신규 출하 등록 (수정은 출하일 상세 팝업에서)
|
||||
fn_openSaleRegPopupWithData(selectedRow);
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
@@ -596,54 +596,46 @@ function fn_calculateSelectedItem() {
|
||||
dataType : "json",
|
||||
success : function(data) {
|
||||
alert(data.msg);
|
||||
|
||||
// 저장 후 잔량 확인을 위해 서버에 다시 조회
|
||||
|
||||
// 수정 모드(logId)면 바로 닫기 (부모 팝업이 자동 새로고침)
|
||||
var logIdVal = $("input[name='logId']").val();
|
||||
if(logIdVal && logIdVal.trim() !== '') {
|
||||
self.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// 신규 등록 모드: 저장 후 잔량 확인
|
||||
$.ajax({
|
||||
url: "/salesMgmt/salesRegForm.do",
|
||||
type: "GET",
|
||||
data: { orderNo: "${param.orderNo}" },
|
||||
dataType: "html",
|
||||
success: function(response) {
|
||||
// 응답에서 SALES_QUANTITY 추출 (잔량)
|
||||
var match = response.match(/SALES_QUANTITY:\s*(\d+)/);
|
||||
var remainingQuantity = match ? parseInt(match[1]) : 0;
|
||||
|
||||
|
||||
console.log("서버에서 계산한 잔량:", remainingQuantity);
|
||||
|
||||
|
||||
if(remainingQuantity > 0) {
|
||||
if(confirm("잔량 " + remainingQuantity + "개가 남았습니다. 계속 등록하시겠습니까?")) {
|
||||
// 부모 창 새로고침 후 팝업 새로고침
|
||||
if(opener && opener.fn_search) {
|
||||
console.log("분할 출하 계속 - 부모 창 fn_search 호출");
|
||||
opener.fn_search();
|
||||
}
|
||||
// 팝업 새로고침 (잔량으로 수량 자동 설정)
|
||||
location.reload();
|
||||
} else {
|
||||
// 목록 새로고침 후 팝업 닫기
|
||||
console.log("분할 출하 중단 - 팝업 닫기");
|
||||
if(opener && opener.fn_search) {
|
||||
console.log("부모 창 fn_search 호출");
|
||||
opener.fn_search();
|
||||
} else {
|
||||
console.log("부모 창 fn_search 없음!");
|
||||
}
|
||||
self.close();
|
||||
}
|
||||
} else {
|
||||
// 목록 새로고침 후 팝업 닫기
|
||||
console.log("잔량 없음 - 팝업 닫기");
|
||||
if(opener && opener.fn_search) {
|
||||
console.log("부모 창 fn_search 호출");
|
||||
opener.fn_search();
|
||||
} else {
|
||||
console.log("부모 창 fn_search 없음!");
|
||||
}
|
||||
self.close();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
// 에러 시 그냥 팝업 닫기
|
||||
if(opener && opener.fn_search) {
|
||||
opener.fn_search();
|
||||
}
|
||||
@@ -680,14 +672,19 @@ function fn_calculateSelectedItem() {
|
||||
<body>
|
||||
<form name="form1" id="form1" action="" method="post">
|
||||
<input type="hidden" name="orderNo" value="${param.orderNo}">
|
||||
<input type="hidden" name="saleNo" value="${param.saleNo}">
|
||||
<input type="hidden" name="logId" value="${logId}">
|
||||
<!-- serialNoList는 name 속성 없이 id만 사용 (클라이언트 전용) -->
|
||||
<input type="hidden" id="serialNoList" value="${saleInfo.SERIAL_NO_LIST}" />
|
||||
|
||||
<section class="business_popup_min_width">
|
||||
<div class="plm_menu_name">
|
||||
<h2>
|
||||
<span>판매 등록 (주문번호: ${param.orderNo})</span>
|
||||
<span>
|
||||
<c:choose>
|
||||
<c:when test="${not empty logId}">출하 수정 (주문번호: ${param.orderNo})</c:when>
|
||||
<c:otherwise>판매 등록 (주문번호: ${param.orderNo})</c:otherwise>
|
||||
</c:choose>
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
font-family: 'Malgun Gothic', sans-serif;
|
||||
width: auto !important;
|
||||
}
|
||||
.popup-header {
|
||||
font-size: 18px;
|
||||
@@ -38,6 +39,15 @@ body {
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
}
|
||||
.shipping-date-link {
|
||||
color: #2196F3;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
.shipping-date-link:hover {
|
||||
color: #1565C0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.btn-close {
|
||||
padding: 8px 20px;
|
||||
background-color: #666;
|
||||
@@ -54,6 +64,24 @@ body {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function fn_openEditPopup(logId, orderNo) {
|
||||
var popup_width = 850;
|
||||
var popup_height = 420;
|
||||
var url = "/salesMgmt/salesRegForm.do?orderNo=" + encodeURIComponent(orderNo) + "&logId=" + logId;
|
||||
var left = (screen.width - popup_width) / 2;
|
||||
var top = (screen.height - popup_height) / 2;
|
||||
var editPopup = window.open(url, "salesRegEdit_" + logId,
|
||||
"width=" + popup_width + ",height=" + popup_height + ",left=" + left + ",top=" + top + ",scrollbars=yes,resizable=yes");
|
||||
|
||||
var checkPopup = setInterval(function() {
|
||||
if(editPopup.closed) {
|
||||
clearInterval(checkPopup);
|
||||
location.reload();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="popup-header">
|
||||
@@ -79,7 +107,12 @@ body {
|
||||
<c:otherwise>
|
||||
<c:forEach items="${shippingList}" var="item">
|
||||
<tr>
|
||||
<td>${item.shipping_date}</td>
|
||||
<td>
|
||||
<span class="shipping-date-link"
|
||||
onclick="fn_openEditPopup('${item.log_id}', '${projectNo}')">
|
||||
${item.shipping_date}
|
||||
</span>
|
||||
</td>
|
||||
<td>${item.shipping_quantity}</td>
|
||||
<td>${item.shipping_order_status}</td>
|
||||
<td>${item.serial_no}</td>
|
||||
|
||||
@@ -423,6 +423,33 @@ body {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* datepicker 팝업이 페이지 리셋 스타일에 영향받지 않도록 보호 */
|
||||
.ui-datepicker {
|
||||
z-index: 9999 !important;
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
padding: 5px;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.ui-datepicker th,
|
||||
.ui-datepicker td {
|
||||
padding: 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ui-datepicker td a,
|
||||
.ui-datepicker td span {
|
||||
display: block;
|
||||
padding: 3px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-datepicker .ui-datepicker-header {
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 버튼 */
|
||||
.button-area {
|
||||
text-align: center;
|
||||
@@ -448,39 +475,68 @@ body {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var today = new Date();
|
||||
// yyyyMMdd 또는 yyyy-MM-dd 형식의 날짜를 "YYYY년 M월 D일 X요일" 형식으로 표시
|
||||
function fn_setDeliveryDate(dateStr) {
|
||||
if(!dateStr) return;
|
||||
|
||||
var year, month, day;
|
||||
if(dateStr.includes("-")) {
|
||||
var parts = dateStr.split("-");
|
||||
year = parseInt(parts[0]);
|
||||
month = parseInt(parts[1]);
|
||||
day = parseInt(parts[2]);
|
||||
} else if(dateStr.length >= 8) {
|
||||
year = parseInt(dateStr.substring(0, 4));
|
||||
month = parseInt(dateStr.substring(4, 6));
|
||||
day = parseInt(dateStr.substring(6, 8));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(isNaN(year) || isNaN(month) || isNaN(day)) return;
|
||||
|
||||
var date = new Date(year, month - 1, day);
|
||||
var days = ['일', '월', '화', '수', '목', '금', '토'];
|
||||
var dateStr = today.getFullYear() + "년 " + (today.getMonth() + 1) + "월 " + today.getDate() + "일 " + days[today.getDay()] + "요일";
|
||||
var displayStr = year + "년 " + month + "월 " + day + "일 " + days[date.getDay()] + "요일";
|
||||
|
||||
// 표시용 날짜 (한글)
|
||||
$("#deliveryDate").text(dateStr);
|
||||
$("#deliveryDate").text(displayStr);
|
||||
|
||||
// 전송용 날짜 (YYYY-MM-DD) - hidden input에 저장
|
||||
var year = today.getFullYear();
|
||||
var month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
var day = String(today.getDate()).padStart(2, '0');
|
||||
var isoDate = year + "-" + month + "-" + day;
|
||||
var isoDate = year + "-" + String(month).padStart(2, '0') + "-" + String(day).padStart(2, '0');
|
||||
$("#deliveryDateISO").val(isoDate);
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
// 기본값: 오늘 날짜
|
||||
var today = new Date();
|
||||
var todayISO = today.getFullYear() + "-" + String(today.getMonth() + 1).padStart(2, '0') + "-" + String(today.getDate()).padStart(2, '0');
|
||||
fn_setDeliveryDate(todayISO);
|
||||
|
||||
// datepicker 초기화
|
||||
$("#deliveryDatePicker").datepicker({
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
dateFormat: 'yy-mm-dd',
|
||||
onSelect: function(dateText) {
|
||||
fn_setDeliveryDate(dateText);
|
||||
}
|
||||
});
|
||||
|
||||
// 달력 아이콘 클릭 시 datepicker 표시
|
||||
$("#deliveryDateCalBtn").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$("#deliveryDatePicker").datepicker("show");
|
||||
});
|
||||
|
||||
fn_loadData();
|
||||
|
||||
// 날짜 수정 시 ISO 형식도 업데이트
|
||||
// 날짜 직접 수정 시 ISO 형식도 업데이트
|
||||
$("#deliveryDate").on('blur', function() {
|
||||
var dateText = $(this).text().trim();
|
||||
// 날짜 파싱 시도
|
||||
try {
|
||||
// "2025년 3월 5일 수요일" 형식 파싱
|
||||
var match = dateText.match(/(\d{4})년\s*(\d+)월\s*(\d+)일/);
|
||||
if (match) {
|
||||
var year = match[1];
|
||||
var month = String(match[2]).padStart(2, '0');
|
||||
var day = String(match[3]).padStart(2, '0');
|
||||
var isoDate = year + "-" + month + "-" + day;
|
||||
$("#deliveryDateISO").val(isoDate);
|
||||
console.log("날짜 업데이트: " + dateText + " → " + isoDate);
|
||||
if(match) {
|
||||
fn_setDeliveryDate(match[1] + "-" + match[2] + "-" + match[3]);
|
||||
}
|
||||
} catch(e) {
|
||||
console.error("날짜 파싱 실패:", e);
|
||||
@@ -623,6 +679,12 @@ function fn_loadSavedStatement(projectObjid, gridData) {
|
||||
// 고객사 정보
|
||||
$("#receiverName").text(firstItem.CUSTOMER || "");
|
||||
|
||||
// 저장된 납품일 복원
|
||||
var savedIsDt = savedData[0].isdt || savedData[0].ISDT || savedData[0].IsDt || "";
|
||||
if(savedIsDt && savedIsDt.length >= 8) {
|
||||
fn_setDeliveryDate(String(savedIsDt));
|
||||
}
|
||||
|
||||
// 품목 테이블 채우기
|
||||
var tbody = $("#itemsBody");
|
||||
tbody.empty();
|
||||
@@ -1041,6 +1103,8 @@ function fn_close() {
|
||||
<td class="date-label-cell">납품일</td>
|
||||
<td class="date-value-cell" colspan="4">
|
||||
<span id="deliveryDate" contenteditable="true">2025년 3월 5일 수요일</span>
|
||||
<img id="deliveryDateCalBtn" src="/images/date_icon.png" alt="달력" class="no-print" style="width:16px;height:16px;cursor:pointer;vertical-align:middle;margin-left:8px;">
|
||||
<input type="text" id="deliveryDatePicker" readonly style="width:1px;height:1px;border:none;padding:0;margin:0;opacity:0;overflow:hidden;">
|
||||
<input type="hidden" id="deliveryDateISO" value="">
|
||||
</td>
|
||||
<td class="supplier-label-cell" rowspan="5">
|
||||
|
||||
@@ -206,9 +206,10 @@ public class EmployeeApiClient {
|
||||
json.append(",\"pId\":\"\"");
|
||||
json.append("}");
|
||||
|
||||
// body 섹션
|
||||
// body 섹션 - extraColumns로 이메일/전화번호 등 추가 필드 요청
|
||||
json.append(",\"body\":{");
|
||||
json.append("\"coCd\":\"").append(escapeJson(coCd)).append("\"");
|
||||
json.append(",\"extraColumns\":[\"emalAdd\",\"outemalAdd\",\"emgcTel\",\"tel\",\"joinDt\"]");
|
||||
json.append("}");
|
||||
|
||||
json.append("}");
|
||||
|
||||
@@ -487,7 +487,8 @@ public class Constants {
|
||||
|
||||
/* SMTP 메일정보 - 영업팀 (견적서 등) */
|
||||
public static final String SMTP_USER_SALES = "sales@rps-korea.com";
|
||||
public static final String SMTP_USER_PW_SALES = "rpstech6125!!";
|
||||
//public static final String SMTP_USER_PW_SALES = "rpstech6125!!";
|
||||
public static final String SMTP_USER_PW_SALES = "rps6125!!";
|
||||
public static final String SMTP_HOST_SALES = "erp.rps-korea.com";
|
||||
public static final int SMTP_PORT_SALES = 25;
|
||||
|
||||
|
||||
@@ -114,9 +114,10 @@
|
||||
data_type = #{data_type}
|
||||
</insert>
|
||||
|
||||
<!-- 사원 정보 UPSERT (실제 JSON 응답 기준) -->
|
||||
<!-- 사원 정보 UPSERT (sabun unique 인덱스 기준) -->
|
||||
<insert id="upsertEmployee" parameterType="map">
|
||||
INSERT INTO user_info (
|
||||
user_id,
|
||||
sabun,
|
||||
empseq,
|
||||
user_password,
|
||||
@@ -128,6 +129,7 @@
|
||||
position_name,
|
||||
rank,
|
||||
email,
|
||||
tel,
|
||||
cell_phone,
|
||||
user_type,
|
||||
user_type_name,
|
||||
@@ -136,6 +138,7 @@
|
||||
data_type,
|
||||
regdate
|
||||
) VALUES (
|
||||
#{sabun},
|
||||
#{sabun},
|
||||
#{empseq},
|
||||
#{user_password},
|
||||
@@ -147,11 +150,12 @@
|
||||
#{position_name},
|
||||
#{rank},
|
||||
#{email},
|
||||
#{tel},
|
||||
#{cell_phone},
|
||||
#{user_type},
|
||||
#{user_type_name},
|
||||
#{status},
|
||||
CASE
|
||||
CASE
|
||||
WHEN #{end_date} IS NULL OR #{end_date} = '' THEN NULL
|
||||
ELSE TO_TIMESTAMP(#{end_date}, 'YYYYMMDD')
|
||||
END,
|
||||
@@ -168,11 +172,12 @@
|
||||
position_name = #{position_name},
|
||||
rank = #{rank},
|
||||
email = #{email},
|
||||
tel = #{tel},
|
||||
cell_phone = #{cell_phone},
|
||||
user_type = #{user_type},
|
||||
user_type_name = #{user_type_name},
|
||||
status = #{status},
|
||||
end_date = CASE
|
||||
end_date = CASE
|
||||
WHEN #{end_date} IS NULL OR #{end_date} = '' THEN NULL
|
||||
ELSE TO_TIMESTAMP(#{end_date}, 'YYYYMMDD')
|
||||
END,
|
||||
|
||||
@@ -3407,17 +3407,32 @@ ORDER BY COALESCE(T.REVISION, '1.0')
|
||||
|
||||
<!-- 프로젝트 OBJID로 MBOM 파트 목록 조회 -->
|
||||
<select id="getMbomPartListByProjectNo" parameterType="map" resultType="map">
|
||||
SELECT PM.OBJID AS CODE
|
||||
, PM.PART_NO || ' - ' || PM.PART_NAME AS NAME
|
||||
, PM.OBJID AS CODE_ID
|
||||
, PM.PART_NO || ' - ' || PM.PART_NAME AS CODE_NAME
|
||||
, PM.PART_NO
|
||||
, PM.PART_NAME
|
||||
FROM MBOM_DETAIL MD
|
||||
INNER JOIN MBOM_HEADER MH ON MH.OBJID = MD.MBOM_HEADER_OBJID
|
||||
INNER JOIN PROJECT_MGMT PJ ON PJ.OBJID = MH.PROJECT_OBJID
|
||||
INNER JOIN PART_MNG PM ON PM.OBJID::VARCHAR = MD.PART_OBJID
|
||||
WHERE PJ.OBJID = #{PROJECT_NO}
|
||||
ORDER BY PM.PART_NO
|
||||
<choose>
|
||||
<when test="PROJECT_NO != null and PROJECT_NO != ''">
|
||||
SELECT PM.OBJID AS CODE
|
||||
, PM.PART_NO || ' - ' || PM.PART_NAME AS NAME
|
||||
, PM.OBJID AS CODE_ID
|
||||
, PM.PART_NO || ' - ' || PM.PART_NAME AS CODE_NAME
|
||||
, PM.PART_NO
|
||||
, PM.PART_NAME
|
||||
FROM MBOM_DETAIL MD
|
||||
INNER JOIN MBOM_HEADER MH ON MH.OBJID = MD.MBOM_HEADER_OBJID
|
||||
INNER JOIN PROJECT_MGMT PJ ON PJ.OBJID = MH.PROJECT_OBJID
|
||||
INNER JOIN PART_MNG PM ON PM.OBJID::VARCHAR = MD.PART_OBJID
|
||||
WHERE PJ.OBJID = #{PROJECT_NO}
|
||||
ORDER BY PM.PART_NO
|
||||
</when>
|
||||
<otherwise>
|
||||
SELECT PM.OBJID AS CODE
|
||||
, PM.PART_NO || ' - ' || PM.PART_NAME AS NAME
|
||||
, PM.OBJID AS CODE_ID
|
||||
, PM.PART_NO || ' - ' || PM.PART_NAME AS CODE_NAME
|
||||
, PM.PART_NO
|
||||
, PM.PART_NAME
|
||||
FROM PART_MNG PM
|
||||
WHERE PM.STATUS = 'release'
|
||||
ORDER BY PM.PART_NO
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -2853,6 +2853,27 @@ public class ContractMgmtController {
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 영업건(CONTRACT)의 전체 S/N 목록 조회
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value="/contractMgmt/getAllSerialNumbers.do", method=RequestMethod.POST)
|
||||
public Map getAllSerialNumbersByContract(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
try {
|
||||
List<String> serialNumbers = contractMgmtService.getAllSerialNumbersByContract(paramMap);
|
||||
resultMap.put("result", "success");
|
||||
resultMap.put("serialNumbers", serialNumbers);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
resultMap.put("result", "error");
|
||||
resultMap.put("message", e.getMessage());
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수주취소 수량 저장
|
||||
*/
|
||||
|
||||
@@ -214,18 +214,14 @@ public class SalesNcollectMgmtController {
|
||||
@RequestMapping(value = "/revenueMgmt/revenueGridList.do", method = RequestMethod.POST)
|
||||
public Map<String, Object> salesMgmtGridList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap) {
|
||||
try {
|
||||
// commonService.selectListPagingNew를 사용하여 페이지네이션 처리
|
||||
commonService.selectListPagingNew("salesNcollectMgmt.getSalesMgmtGridList", request, paramMap);
|
||||
|
||||
// Total 합계 조회 (기존 로직 유지)
|
||||
Map<String, Object> totals = salesNcollectMgmtService.getSalesMgmtTotals(paramMap);
|
||||
commonService.selectListPagingNew("salesNcollectMgmt.getRevenueMgmtGridList", request, paramMap);
|
||||
|
||||
Map<String, Object> totals = salesNcollectMgmtService.getRevenueMgmtTotals(paramMap);
|
||||
paramMap.put("TOTALS", totals);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
// 에러 발생 시 빈 데이터 설정
|
||||
paramMap.put("RESULTLIST", new java.util.ArrayList<>());
|
||||
|
||||
// Total 초기화
|
||||
|
||||
Map<String, Object> emptyTotals = new HashMap<String, Object>();
|
||||
emptyTotals.put("TOTAL_SUPPLY_PRICE", 0);
|
||||
emptyTotals.put("TOTAL_VAT", 0);
|
||||
@@ -352,6 +348,22 @@ public class SalesNcollectMgmtController {
|
||||
return "/salesmgmt/salesMgmt/projectDetailView";
|
||||
}
|
||||
}
|
||||
// logId가 있으면 shipment_log 수정 모드
|
||||
else if(paramMap.get("logId") != null && !paramMap.get("logId").equals("")) {
|
||||
System.out.println("=== shipment_log 수정 모드 (logId: " + paramMap.get("logId") + ") ===");
|
||||
saleInfo = salesNcollectMgmtService.getShipmentLogById((String) paramMap.get("logId"));
|
||||
|
||||
if(saleInfo != null) {
|
||||
salesCurrency = CommonUtils.nullToEmpty((String)saleInfo.get("SALES_CURRENCY"));
|
||||
request.setAttribute("logId", paramMap.get("logId"));
|
||||
|
||||
System.out.println("=== shipment_log 조회 완료 ===");
|
||||
System.out.println("LOG_ID: " + paramMap.get("logId"));
|
||||
System.out.println("SALES_QUANTITY: " + saleInfo.get("SALES_QUANTITY"));
|
||||
System.out.println("SHIPPING_DATE: " + saleInfo.get("SHIPPING_DATE"));
|
||||
System.out.println("SERIAL_NO: " + saleInfo.get("SERIAL_NO"));
|
||||
}
|
||||
}
|
||||
// saleNo가 있지만 "detail"이 아니면 판매등록 수정 모드 - getSaleInfo로 S/N 포함 조회
|
||||
else if(paramMap.get("saleNo") != null && !paramMap.get("saleNo").equals("")) {
|
||||
System.out.println("=== 판매등록 수정 모드 ===");
|
||||
@@ -359,10 +371,10 @@ public class SalesNcollectMgmtController {
|
||||
saleInfoParam.put("orderNo", paramMap.get("orderNo"));
|
||||
saleInfoParam.put("saleNo", paramMap.get("saleNo"));
|
||||
saleInfo = salesNcollectMgmtService.getSaleInfo(saleInfoParam);
|
||||
|
||||
|
||||
if(saleInfo != null) {
|
||||
salesCurrency = CommonUtils.nullToEmpty((String)saleInfo.get("SALES_CURRENCY"));
|
||||
|
||||
|
||||
System.out.println("=== 판매등록 수정 모드 조회 완료 ===");
|
||||
System.out.println("SALE_NO: " + saleInfo.get("SALE_NO"));
|
||||
System.out.println("ORDER_QUANTITY: " + saleInfo.get("ORDER_QUANTITY"));
|
||||
|
||||
@@ -561,9 +561,10 @@
|
||||
WHEN AMR.STATUS = 'reject' THEN '반려'
|
||||
WHEN AMR.STATUS = 'create' THEN '작성중'
|
||||
WHEN AMR.STATUS = 'notRequired' THEN '결재불필요'
|
||||
WHEN COALESCE(T.APPROVAL_REQUIRED, 'N') = 'N' THEN '결재불필요'
|
||||
ELSE ''
|
||||
END AS APPR_STATUS
|
||||
,COALESCE(AMR.STATUS, '') AS AMARANTH_STATUS
|
||||
,COALESCE(AMR.STATUS, CASE WHEN COALESCE(T.APPROVAL_REQUIRED, 'N') = 'N' THEN 'notRequired' ELSE '' END) AS AMARANTH_STATUS
|
||||
,CASE
|
||||
WHEN AMR_ORDER.STATUS = 'complete' THEN '결재완료'
|
||||
WHEN AMR_ORDER.STATUS = 'inProcess' THEN '결재중'
|
||||
@@ -1285,6 +1286,7 @@
|
||||
,QUANTITY
|
||||
,CUSTOMER_REQUEST
|
||||
,EXCHANGE_RATE
|
||||
,APPROVAL_REQUIRED
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@@ -1345,6 +1347,7 @@
|
||||
,#{quantity}
|
||||
,#{customer_request}
|
||||
,#{exchange_rate}
|
||||
,COALESCE(#{approval_required}, 'N')
|
||||
)
|
||||
ON CONFLICT (OBJID) DO
|
||||
UPDATE
|
||||
@@ -1402,6 +1405,7 @@
|
||||
,QUANTITY = #{quantity}
|
||||
,CUSTOMER_REQUEST = #{customer_request}
|
||||
,EXCHANGE_RATE = #{exchange_rate}
|
||||
,APPROVAL_REQUIRED = COALESCE(#{approval_required}, 'N')
|
||||
</update>
|
||||
|
||||
<update id="saveContractMgmtInfo_old" parameterType="map">
|
||||
@@ -1792,6 +1796,7 @@ SELECT
|
||||
,A.QUANTITY
|
||||
,A.CUSTOMER_REQUEST
|
||||
,A.EXCHANGE_RATE
|
||||
,COALESCE(A.APPROVAL_REQUIRED, 'N') AS APPROVAL_REQUIRED
|
||||
,A.ORDER_DATE
|
||||
,A.ORDER_UNIT_PRICE
|
||||
,A.ORDER_SUPPLY_PRICE
|
||||
@@ -5691,6 +5696,18 @@ WHERE
|
||||
WHERE ITEM_OBJID = #{itemObjId}
|
||||
</delete>
|
||||
|
||||
<!-- 영업건(CONTRACT)의 전체 S/N 조회 -->
|
||||
<select id="getAllSerialNumbersByContract" parameterType="map" resultType="string">
|
||||
SELECT CIS.SERIAL_NO
|
||||
FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
|
||||
WHERE CI.CONTRACT_OBJID = #{contractObjId}
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND CIS.SERIAL_NO IS NOT NULL
|
||||
AND CIS.SERIAL_NO != ''
|
||||
ORDER BY CI.SEQ, CIS.SEQ
|
||||
</select>
|
||||
|
||||
<!-- 고객사 담당자 정보 조회 -->
|
||||
<select id="getCustomerContactInfo" parameterType="map" resultType="map">
|
||||
SELECT
|
||||
|
||||
@@ -1700,21 +1700,33 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
|
||||
-- 출하일 기본값: 오늘 날짜
|
||||
TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD') AS SHIPPING_DATE,
|
||||
|
||||
|
||||
-- 담당자
|
||||
CM.PM_USER_ID AS MANAGER
|
||||
|
||||
CM.PM_USER_ID AS MANAGER,
|
||||
|
||||
-- 기존 S/N (CONTRACT_ITEM_SERIAL 마스터에서 조회)
|
||||
COALESCE((
|
||||
SELECT STRING_AGG(CIS2.SERIAL_NO, ',' ORDER BY CIS2.SEQ)
|
||||
FROM CONTRACT_ITEM CI2
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS2 ON CI2.OBJID = CIS2.ITEM_OBJID AND CIS2.STATUS = 'ACTIVE'
|
||||
WHERE CI2.CONTRACT_OBJID = PM.CONTRACT_OBJID
|
||||
AND CI2.PART_OBJID = PM.PART_OBJID
|
||||
AND CI2.STATUS = 'ACTIVE'
|
||||
), '') AS SERIAL_NO
|
||||
|
||||
FROM PROJECT_MGMT PM
|
||||
INNER JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
|
||||
LEFT JOIN CONTRACT_ITEM CI ON CM.OBJID::VARCHAR = CI.CONTRACT_OBJID AND UPPER(CI.STATUS) = 'ACTIVE'
|
||||
WHERE PM.PROJECT_NO = #{orderNo}
|
||||
GROUP BY
|
||||
GROUP BY
|
||||
CM.CONTRACT_NO,
|
||||
CM.OBJID,
|
||||
CM.CONTRACT_CURRENCY,
|
||||
CM.EXCHANGE_RATE,
|
||||
CM.PM_USER_ID,
|
||||
PM.QUANTITY
|
||||
PM.QUANTITY,
|
||||
PM.CONTRACT_OBJID,
|
||||
PM.PART_OBJID
|
||||
</select>
|
||||
|
||||
<!--
|
||||
@@ -1945,7 +1957,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
<if test="salesExchangeRate != null and salesExchangeRate != ''">
|
||||
, sales_exchange_rate = #{salesExchangeRate}::numeric
|
||||
</if>
|
||||
WHERE sale_no = #{saleNo}
|
||||
WHERE sale_no = #{saleNo}::integer
|
||||
</update>
|
||||
|
||||
<!-- PROJECT_MGMT의 OBJID 조회 (shipment_log의 target_objid로 사용) -->
|
||||
@@ -1957,19 +1969,98 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
<!-- 출하일 상세 내역 조회 (모든 분할 출하 포함) -->
|
||||
<select id="getShippingDetailList" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getShippingDetailList - shipment_log에서 모든 분할 출하 조회 */
|
||||
SELECT
|
||||
SELECT
|
||||
SL.log_id,
|
||||
COALESCE(TO_CHAR(SL.shipping_date, 'YYYY-MM-DD'), '미등록') AS shipping_date,
|
||||
COALESCE(SL.split_quantity, 0) AS shipping_quantity,
|
||||
COALESCE(SL.shipping_status, '미등록') AS shipping_order_status,
|
||||
COALESCE(SL.serial_no, '-') AS serial_no,
|
||||
COALESCE((
|
||||
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
|
||||
FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
|
||||
JOIN PROJECT_MGMT PM ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID AND PM.PART_OBJID = CI.PART_OBJID
|
||||
WHERE PM.PROJECT_NO = SL.target_objid AND CI.STATUS = 'ACTIVE'
|
||||
), '-') AS serial_no,
|
||||
SL.target_objid AS project_no,
|
||||
'분할 출하 ' || SL.log_id AS source,
|
||||
TO_CHAR(SL.reg_date, 'YYYY-MM-DD HH24:MI:SS') AS reg_date
|
||||
FROM shipment_log SL
|
||||
FROM shipment_log SL
|
||||
WHERE SL.target_objid = #{projectNo}
|
||||
ORDER BY SL.shipping_date DESC, SL.log_id DESC
|
||||
</select>
|
||||
|
||||
|
||||
<!-- shipment_log 단건 조회 (수정 팝업용) -->
|
||||
<select id="getShipmentLogById" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getShipmentLogById - shipment_log 단건 조회 */
|
||||
SELECT
|
||||
SL.log_id,
|
||||
SL.target_objid,
|
||||
COALESCE(TO_CHAR(SL.shipping_date, 'YYYY-MM-DD'), '') AS SHIPPING_DATE,
|
||||
COALESCE(SL.split_quantity, 0) AS SALES_QUANTITY,
|
||||
COALESCE(SL.shipping_status, '') AS SHIPPING_ORDER_STATUS,
|
||||
COALESCE(SL.shipping_method, '') AS SHIPPING_METHOD,
|
||||
COALESCE((
|
||||
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
|
||||
FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
|
||||
JOIN PROJECT_MGMT PM ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID AND PM.PART_OBJID = CI.PART_OBJID
|
||||
WHERE PM.PROJECT_NO = SL.target_objid AND CI.STATUS = 'ACTIVE'
|
||||
), '') AS SERIAL_NO,
|
||||
COALESCE(SL.sales_unit_price, 0) AS SALES_UNIT_PRICE,
|
||||
COALESCE(SL.sales_supply_price, 0) AS SALES_SUPPLY_PRICE,
|
||||
COALESCE(SL.sales_vat, 0) AS SALES_VAT,
|
||||
COALESCE(SL.sales_total_amount, 0) AS SALES_TOTAL_AMOUNT,
|
||||
COALESCE(SL.sales_currency, '') AS SALES_CURRENCY,
|
||||
COALESCE(SL.sales_exchange_rate, 0) AS SALES_EXCHANGE_RATE,
|
||||
COALESCE(SL.manager_user_id, '') AS MANAGER,
|
||||
COALESCE(SL.incoterms, '') AS INCOTERMS,
|
||||
COALESCE(SL.original_quantity, 0) AS ORDER_QUANTITY,
|
||||
COALESCE(SL.remaining_quantity, 0) AS REMAINING_QUANTITY
|
||||
FROM shipment_log SL
|
||||
WHERE SL.log_id = #{logId}::integer
|
||||
</select>
|
||||
|
||||
<!-- shipment_log 수정 -->
|
||||
<update id="updateShipmentLog" parameterType="map">
|
||||
/* salesNcollectMgmt.updateShipmentLog - shipment_log 수정 */
|
||||
UPDATE shipment_log SET
|
||||
split_quantity = #{salesQuantity}::integer,
|
||||
shipping_status = #{shippingOrderStatus}
|
||||
<if test="shippingDate != null and shippingDate != ''">
|
||||
, shipping_date = TO_DATE(#{shippingDate}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="shippingMethod != null and shippingMethod != ''">
|
||||
, shipping_method = #{shippingMethod}
|
||||
</if>
|
||||
<if test="serialNo != null and serialNo != ''">
|
||||
, serial_no = #{serialNo}
|
||||
</if>
|
||||
<if test="salesUnitPrice != null and salesUnitPrice != ''">
|
||||
, sales_unit_price = #{salesUnitPrice}::numeric
|
||||
</if>
|
||||
<if test="salesSupplyPrice != null and salesSupplyPrice != ''">
|
||||
, sales_supply_price = #{salesSupplyPrice}::numeric
|
||||
</if>
|
||||
<if test="salesVat != null and salesVat != ''">
|
||||
, sales_vat = #{salesVat}::numeric
|
||||
</if>
|
||||
<if test="salesTotalAmount != null and salesTotalAmount != ''">
|
||||
, sales_total_amount = #{salesTotalAmount}::numeric
|
||||
</if>
|
||||
<if test="salesCurrency != null and salesCurrency != ''">
|
||||
, sales_currency = #{salesCurrency}
|
||||
</if>
|
||||
<if test="salesExchangeRate != null and salesExchangeRate != ''">
|
||||
, sales_exchange_rate = #{salesExchangeRate}::numeric
|
||||
</if>
|
||||
<if test="managerUserId != null and managerUserId != ''">
|
||||
, manager_user_id = #{managerUserId}
|
||||
</if>
|
||||
<if test="incoterms != null and incoterms != ''">
|
||||
, incoterms = #{incoterms}
|
||||
</if>
|
||||
WHERE log_id = #{logId}::integer
|
||||
</update>
|
||||
|
||||
<!-- 거래명세서 - 고객 정보 조회 -->
|
||||
<select id="getCustomerInfoByProjectNo" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getCustomerInfoByProjectNo - 프로젝트 번호로 고객 정보 조회 */
|
||||
@@ -2268,5 +2359,372 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
WHERE OBJID::VARCHAR = #{OBJID}
|
||||
</update>
|
||||
|
||||
<!-- ==================== 매출관리 출하건별 분리 쿼리 ==================== -->
|
||||
|
||||
<!-- 매출관리 그리드 목록 - shipment_log 기반 (출하건별 1행) -->
|
||||
<select id="getRevenueMgmtGridList" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getRevenueMgmtGridList - shipment_log 기반 매출관리 조회 */
|
||||
SELECT
|
||||
T.OBJID,
|
||||
T.PROJECT_NO,
|
||||
T.CONTRACT_OBJID,
|
||||
SL.log_id AS LOG_ID,
|
||||
COALESCE(SL.sales_deadline_date, '') AS SALES_DEADLINE_DATE,
|
||||
COALESCE(SL.tax_type, '') AS TAX_TYPE,
|
||||
COALESCE(CODE_NAME(SL.tax_type), '') AS TAX_TYPE_NAME,
|
||||
COALESCE(SL.tax_invoice_date, '') AS TAX_INVOICE_DATE,
|
||||
COALESCE(SL.export_decl_no, '') AS EXPORT_DECL_NO,
|
||||
COALESCE(SL.loading_date, '') AS LOADING_DATE,
|
||||
CODE_NAME(T.CATEGORY_CD) AS ORDER_TYPE,
|
||||
CODE_NAME(T.PRODUCT) AS PRODUCT_TYPE,
|
||||
CODE_NAME(T.AREA_CD) AS NATION,
|
||||
CASE
|
||||
WHEN T.CUSTOMER_OBJID LIKE 'C_%' THEN
|
||||
(SELECT CLIENT_NM FROM CLIENT_MNG AS C WHERE 'C_' || C.OBJID::VARCHAR = T.CUSTOMER_OBJID)
|
||||
ELSE
|
||||
(SELECT SUPPLY_NAME FROM SUPPLY_MNG AS O WHERE O.OBJID::VARCHAR = T.CUSTOMER_OBJID::VARCHAR)
|
||||
END AS CUSTOMER,
|
||||
T.PART_NO AS PRODUCT_NO,
|
||||
T.PART_NAME AS PRODUCT_NAME,
|
||||
COALESCE((
|
||||
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
|
||||
FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID AND CI.STATUS = 'ACTIVE'
|
||||
), '') AS SERIAL_NO,
|
||||
COALESCE(T.QUANTITY::numeric, 0) AS ORDER_QUANTITY,
|
||||
(SELECT CM.PO_NO FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID) AS PO_NO,
|
||||
COALESCE(T.CONTRACT_DATE, (SELECT CM.order_date FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID)) AS ORDER_DATE,
|
||||
COALESCE(SL.split_quantity, 0) AS SALES_QUANTITY,
|
||||
COALESCE(SL.sales_unit_price, 0) AS SALES_UNIT_PRICE,
|
||||
COALESCE(SL.sales_supply_price, 0) AS SALES_SUPPLY_PRICE,
|
||||
COALESCE(SL.sales_vat, 0) AS SALES_VAT,
|
||||
COALESCE(SL.sales_total_amount, 0) AS SALES_TOTAL_AMOUNT,
|
||||
COALESCE(SL.sales_total_amount, 0) AS SALES_TOTAL_AMOUNT_KRW,
|
||||
COALESCE(SL.sales_currency, T.CONTRACT_CURRENCY) AS SALES_CURRENCY,
|
||||
CODE_NAME(COALESCE(SL.sales_currency, T.CONTRACT_CURRENCY)) AS SALES_CURRENCY_NAME,
|
||||
COALESCE(SL.sales_exchange_rate, 0) AS SALES_EXCHANGE_RATE,
|
||||
COALESCE(TO_CHAR(SL.shipping_date, 'YYYY-MM-DD'), '') AS SHIPPING_DATE,
|
||||
COALESCE(SL.shipping_method, '') AS SHIPPING_METHOD,
|
||||
COALESCE(
|
||||
(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = SL.manager_user_id),
|
||||
(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = T.PM_USER_ID)
|
||||
) AS MANAGER,
|
||||
COALESCE(SL.incoterms, '') AS INCOTERMS,
|
||||
CASE
|
||||
WHEN SL.sales_deadline_date IS NOT NULL AND SL.sales_deadline_date != '' THEN '완료'
|
||||
ELSE ''
|
||||
END AS SALES_STATUS
|
||||
FROM PROJECT_MGMT AS T
|
||||
INNER JOIN shipment_log SL ON SL.target_objid = T.PROJECT_NO
|
||||
WHERE 1 = 1
|
||||
AND T.PROJECT_NO IS NOT NULL
|
||||
AND T.PROJECT_NO != ''
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND CODE_NAME(CM.CONTRACT_RESULT) IN ('수주(FCST)', '수주')
|
||||
)
|
||||
<if test="orderType != null and orderType != ''">
|
||||
AND T.CATEGORY_CD = #{orderType}
|
||||
</if>
|
||||
<if test="productType != null and productType != ''">
|
||||
AND T.PRODUCT = #{productType}
|
||||
</if>
|
||||
<if test="nation != null and nation != ''">
|
||||
AND T.AREA_CD = #{nation}
|
||||
</if>
|
||||
<if test="customer_objid != null and customer_objid != ''">
|
||||
AND T.CUSTOMER_OBJID = #{customer_objid}
|
||||
</if>
|
||||
<if test="(search_partNo != null and search_partNo != '') or (search_partName != null and search_partName != '')">
|
||||
AND (
|
||||
<if test="search_partNo != null and search_partNo != ''">
|
||||
T.PART_NO = #{search_partNo}
|
||||
</if>
|
||||
<if test="(search_partNo != null and search_partNo != '') and (search_partName != null and search_partName != '')">
|
||||
OR
|
||||
</if>
|
||||
<if test="search_partName != null and search_partName != ''">
|
||||
T.PART_NAME = #{search_partName}
|
||||
</if>
|
||||
)
|
||||
</if>
|
||||
<if test="serialNo != null and serialNo != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
|
||||
AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
)
|
||||
</if>
|
||||
<if test="poNo != null and poNo != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND UPPER(CM.PO_NO) LIKE UPPER(CONCAT('%', #{poNo}, '%'))
|
||||
)
|
||||
</if>
|
||||
<if test="orderDateFrom != null and orderDateFrom != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND TO_DATE(CM.ORDER_DATE, 'YYYY-MM-DD') <![CDATA[>=]]> TO_DATE(#{orderDateFrom}, 'YYYY-MM-DD')
|
||||
)
|
||||
</if>
|
||||
<if test="orderDateTo != null and orderDateTo != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND TO_DATE(CM.ORDER_DATE, 'YYYY-MM-DD') <![CDATA[<=]]> TO_DATE(#{orderDateTo}, 'YYYY-MM-DD')
|
||||
)
|
||||
</if>
|
||||
<if test="shippingDateFrom != null and shippingDateFrom != ''">
|
||||
AND SL.shipping_date <![CDATA[>=]]> TO_DATE(#{shippingDateFrom}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="shippingDateTo != null and shippingDateTo != ''">
|
||||
AND SL.shipping_date <![CDATA[<=]]> TO_DATE(#{shippingDateTo}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="salesDeadlineFrom != null and salesDeadlineFrom != ''">
|
||||
AND SL.sales_deadline_date IS NOT NULL
|
||||
AND TO_DATE(SL.sales_deadline_date, 'YYYY-MM-DD') <![CDATA[>=]]> TO_DATE(#{salesDeadlineFrom}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="salesDeadlineTo != null and salesDeadlineTo != ''">
|
||||
AND SL.sales_deadline_date IS NOT NULL
|
||||
AND TO_DATE(SL.sales_deadline_date, 'YYYY-MM-DD') <![CDATA[<=]]> TO_DATE(#{salesDeadlineTo}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
ORDER BY SL.shipping_date DESC, SL.log_id DESC
|
||||
LIMIT #{COUNT_PER_PAGE} OFFSET (#{PAGE_INDEX} - 1) * #{COUNT_PER_PAGE}
|
||||
</select>
|
||||
|
||||
<!-- 매출관리 그리드 목록 개수 - shipment_log 기반 -->
|
||||
<select id="getRevenueMgmtGridListCount" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getRevenueMgmtGridListCount - shipment_log 기반 개수 */
|
||||
SELECT
|
||||
CEIL(COUNT(1)::float / #{COUNT_PER_PAGE}::float)::numeric::integer AS MAX_PAGE_SIZE,
|
||||
COUNT(1)::integer AS TOTAL_CNT
|
||||
FROM PROJECT_MGMT AS T
|
||||
INNER JOIN shipment_log SL ON SL.target_objid = T.PROJECT_NO
|
||||
WHERE 1 = 1
|
||||
AND T.PROJECT_NO IS NOT NULL
|
||||
AND T.PROJECT_NO != ''
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND CODE_NAME(CM.CONTRACT_RESULT) IN ('수주(FCST)', '수주')
|
||||
)
|
||||
<if test="orderType != null and orderType != ''">
|
||||
AND T.CATEGORY_CD = #{orderType}
|
||||
</if>
|
||||
<if test="productType != null and productType != ''">
|
||||
AND T.PRODUCT = #{productType}
|
||||
</if>
|
||||
<if test="nation != null and nation != ''">
|
||||
AND T.AREA_CD = #{nation}
|
||||
</if>
|
||||
<if test="customer_objid != null and customer_objid != ''">
|
||||
AND T.CUSTOMER_OBJID = #{customer_objid}
|
||||
</if>
|
||||
<if test="(search_partNo != null and search_partNo != '') or (search_partName != null and search_partName != '')">
|
||||
AND (
|
||||
<if test="search_partNo != null and search_partNo != ''">
|
||||
T.PART_NO = #{search_partNo}
|
||||
</if>
|
||||
<if test="(search_partNo != null and search_partNo != '') and (search_partName != null and search_partName != '')">
|
||||
OR
|
||||
</if>
|
||||
<if test="search_partName != null and search_partName != ''">
|
||||
T.PART_NAME = #{search_partName}
|
||||
</if>
|
||||
)
|
||||
</if>
|
||||
<if test="serialNo != null and serialNo != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
|
||||
AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
|
||||
AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
)
|
||||
</if>
|
||||
<if test="poNo != null and poNo != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND UPPER(CM.PO_NO) LIKE UPPER(CONCAT('%', #{poNo}, '%'))
|
||||
)
|
||||
</if>
|
||||
<if test="orderDateFrom != null and orderDateFrom != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND TO_DATE(CM.ORDER_DATE, 'YYYY-MM-DD') <![CDATA[>=]]> TO_DATE(#{orderDateFrom}, 'YYYY-MM-DD')
|
||||
)
|
||||
</if>
|
||||
<if test="orderDateTo != null and orderDateTo != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND TO_DATE(CM.ORDER_DATE, 'YYYY-MM-DD') <![CDATA[<=]]> TO_DATE(#{orderDateTo}, 'YYYY-MM-DD')
|
||||
)
|
||||
</if>
|
||||
<if test="shippingDateFrom != null and shippingDateFrom != ''">
|
||||
AND SL.shipping_date <![CDATA[>=]]> TO_DATE(#{shippingDateFrom}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="shippingDateTo != null and shippingDateTo != ''">
|
||||
AND SL.shipping_date <![CDATA[<=]]> TO_DATE(#{shippingDateTo}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="salesDeadlineFrom != null and salesDeadlineFrom != ''">
|
||||
AND SL.sales_deadline_date IS NOT NULL
|
||||
AND TO_DATE(SL.sales_deadline_date, 'YYYY-MM-DD') <![CDATA[>=]]> TO_DATE(#{salesDeadlineFrom}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="salesDeadlineTo != null and salesDeadlineTo != ''">
|
||||
AND SL.sales_deadline_date IS NOT NULL
|
||||
AND TO_DATE(SL.sales_deadline_date, 'YYYY-MM-DD') <![CDATA[<=]]> TO_DATE(#{salesDeadlineTo}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 매출관리 합계 조회 - shipment_log 기반 -->
|
||||
<select id="getRevenueMgmtTotals" parameterType="map" resultType="map">
|
||||
/* salesNcollectMgmt.getRevenueMgmtTotals - shipment_log 기반 합계 */
|
||||
SELECT
|
||||
COALESCE(SUM(COALESCE(SL.sales_supply_price, 0)), 0)::numeric AS TOTAL_SUPPLY_PRICE,
|
||||
COALESCE(SUM(COALESCE(SL.sales_vat, 0)), 0)::numeric AS TOTAL_VAT,
|
||||
COALESCE(SUM(COALESCE(SL.sales_total_amount, 0)), 0)::numeric AS TOTAL_AMOUNT
|
||||
FROM PROJECT_MGMT T
|
||||
INNER JOIN shipment_log SL ON SL.target_objid = T.PROJECT_NO
|
||||
WHERE 1 = 1
|
||||
AND T.PROJECT_NO IS NOT NULL AND T.PROJECT_NO != ''
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID = T.CONTRACT_OBJID
|
||||
AND CODE_NAME(CM.CONTRACT_RESULT) IN ('수주(FCST)', '수주')
|
||||
)
|
||||
<if test="orderType != null and orderType != ''">
|
||||
AND T.CATEGORY_CD = #{orderType}
|
||||
</if>
|
||||
<if test="productType != null and productType != ''">
|
||||
AND T.PRODUCT = #{productType}
|
||||
</if>
|
||||
<if test="nation != null and nation != ''">
|
||||
AND T.AREA_CD = #{nation}
|
||||
</if>
|
||||
<if test="customer_objid != null and customer_objid != ''">
|
||||
AND T.CUSTOMER_OBJID = #{customer_objid}
|
||||
</if>
|
||||
<if test="serialNo != null and serialNo != ''">
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM CONTRACT_ITEM CI
|
||||
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
|
||||
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID AND CI.PART_OBJID = T.PART_OBJID
|
||||
AND CI.STATUS = 'ACTIVE' AND UPPER(CIS.STATUS) = 'ACTIVE'
|
||||
AND UPPER(CIS.SERIAL_NO) LIKE UPPER('%' || #{serialNo} || '%')
|
||||
)
|
||||
</if>
|
||||
<if test="poNo != null and poNo != ''">
|
||||
AND EXISTS (SELECT 1 FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID AND CM.PO_NO LIKE '%' || #{poNo} || '%')
|
||||
</if>
|
||||
<if test="shippingDateFrom != null and shippingDateFrom != ''">
|
||||
AND SL.shipping_date <![CDATA[>=]]> TO_DATE(#{shippingDateFrom}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="shippingDateTo != null and shippingDateTo != ''">
|
||||
AND SL.shipping_date <![CDATA[<=]]> TO_DATE(#{shippingDateTo}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="salesDeadlineFrom != null and salesDeadlineFrom != ''">
|
||||
AND SL.sales_deadline_date IS NOT NULL
|
||||
AND TO_DATE(SL.sales_deadline_date, 'YYYY-MM-DD') <![CDATA[>=]]> TO_DATE(#{salesDeadlineFrom}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
<if test="salesDeadlineTo != null and salesDeadlineTo != ''">
|
||||
AND SL.sales_deadline_date IS NOT NULL
|
||||
AND TO_DATE(SL.sales_deadline_date, 'YYYY-MM-DD') <![CDATA[<=]]> TO_DATE(#{salesDeadlineTo}, 'YYYY-MM-DD')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 매출마감 전표연동용 데이터 조회 - shipment_log 기반 (log_id로 조회) -->
|
||||
<select id="getSlipDataForDeadlineByLogId" parameterType="map" resultType="com.pms.common.UpperKeyMap">
|
||||
/* salesNcollectMgmt.getSlipDataForDeadlineByLogId - 출하건별 전표 데이터 조회 */
|
||||
SELECT
|
||||
PM.OBJID,
|
||||
PM.PROJECT_NO,
|
||||
PM.AREA_CD,
|
||||
PM.CUSTOMER_OBJID,
|
||||
PM.PART_NO,
|
||||
PM.PART_NAME,
|
||||
SL.log_id AS LOG_ID,
|
||||
COALESCE(SL.tax_type, '') AS TAX_TYPE,
|
||||
COALESCE(SL.tax_invoice_date, '') AS TAX_INVOICE_DATE,
|
||||
COALESCE(SL.export_decl_no, '') AS EXPORT_DECL_NO,
|
||||
COALESCE(SL.loading_date, '') AS LOADING_DATE,
|
||||
COALESCE(SL.sales_deadline_date, '') AS SALES_STATUS,
|
||||
CASE WHEN PM.CUSTOMER_OBJID LIKE 'C_%' THEN
|
||||
(SELECT C.CLIENT_CD FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = PM.CUSTOMER_OBJID)
|
||||
ELSE NULL END AS ERP_CLIENT_CD,
|
||||
CASE WHEN PM.CUSTOMER_OBJID LIKE 'C_%' THEN
|
||||
(SELECT C.CLIENT_NM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = PM.CUSTOMER_OBJID)
|
||||
ELSE
|
||||
(SELECT S.SUPPLY_NAME FROM SUPPLY_MNG S WHERE S.OBJID::VARCHAR = PM.CUSTOMER_OBJID::VARCHAR)
|
||||
END AS CUSTOMER_NAME,
|
||||
CASE WHEN PM.CUSTOMER_OBJID LIKE 'C_%' THEN
|
||||
(SELECT C.BUS_REG_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = PM.CUSTOMER_OBJID)
|
||||
ELSE NULL END AS BUS_REG_NO,
|
||||
COALESCE(SL.sales_supply_price, 0) AS SALES_SUPPLY_PRICE,
|
||||
COALESCE(SL.sales_vat, 0) AS SALES_VAT,
|
||||
COALESCE(SL.sales_total_amount, 0) AS SALES_TOTAL_AMOUNT,
|
||||
COALESCE(SL.sales_currency, PM.CONTRACT_CURRENCY) AS SALES_CURRENCY,
|
||||
COALESCE(SL.sales_exchange_rate, 0) AS SALES_EXCHANGE_RATE,
|
||||
CASE WHEN COALESCE(SL.sales_exchange_rate, 0) > 0 THEN
|
||||
ROUND(COALESCE(SL.sales_total_amount, 0)::NUMERIC / SL.sales_exchange_rate::NUMERIC, 2)
|
||||
ELSE 0 END AS FOREIGN_AMOUNT
|
||||
FROM shipment_log SL
|
||||
INNER JOIN PROJECT_MGMT PM ON PM.PROJECT_NO = SL.target_objid
|
||||
WHERE SL.log_id = #{logId}::integer
|
||||
</select>
|
||||
|
||||
<!-- shipment_log 마감정보 저장 -->
|
||||
<update id="saveShipmentLogDeadlineInfo" parameterType="map">
|
||||
/* salesNcollectMgmt.saveShipmentLogDeadlineInfo - 출하건별 마감정보 저장 */
|
||||
UPDATE shipment_log SET
|
||||
tax_type = #{taxType}
|
||||
<if test="taxInvoiceDate != null and taxInvoiceDate != ''">, tax_invoice_date = #{taxInvoiceDate}</if>
|
||||
<if test="exportDeclNo != null">, export_decl_no = #{exportDeclNo}</if>
|
||||
<if test="loadingDate != null and loadingDate != ''">, loading_date = #{loadingDate}</if>
|
||||
WHERE log_id = #{logId}::integer
|
||||
</update>
|
||||
|
||||
<!-- shipment_log 전표 정보 저장 + 마감 처리 -->
|
||||
<update id="updateShipmentLogSlipInfo" parameterType="map">
|
||||
/* salesNcollectMgmt.updateShipmentLogSlipInfo - 출하건별 전표 연동 정보 저장 */
|
||||
UPDATE shipment_log SET
|
||||
sales_deadline_date = #{deadlineDate},
|
||||
sales_slip_date = #{slipDate},
|
||||
sales_slip_menu_sq = #{slipMenuSq}
|
||||
WHERE log_id = #{logId}::integer
|
||||
</update>
|
||||
|
||||
<!-- 프로젝트의 모든 shipment_log 마감 여부 확인 -->
|
||||
<select id="checkAllShipmentLogClosed" parameterType="map" resultType="int">
|
||||
/* salesNcollectMgmt.checkAllShipmentLogClosed - 미마감 건수 조회 */
|
||||
SELECT COUNT(1)
|
||||
FROM shipment_log
|
||||
WHERE target_objid = #{projectNo}
|
||||
AND (sales_deadline_date IS NULL OR sales_deadline_date = '')
|
||||
</select>
|
||||
|
||||
<!-- 프로젝트 전체 마감 시 PROJECT_MGMT 상태 업데이트 -->
|
||||
<update id="updateProjectSalesStatus" parameterType="map">
|
||||
/* salesNcollectMgmt.updateProjectSalesStatus - 모든 출하건 마감 시 프로젝트 '완료' 처리 */
|
||||
UPDATE PROJECT_MGMT
|
||||
SET SALES_STATUS = '완료',
|
||||
SALES_DEADLINE_DATE = #{deadlineDate}
|
||||
WHERE PROJECT_NO = #{projectNo}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
|
||||
|
||||
@@ -2490,7 +2490,27 @@ private String encodeImageToBase64(String imagePath) {
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 영업건(CONTRACT)의 전체 S/N 목록 조회
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public List<String> getAllSerialNumbersByContract(Map<String, Object> paramMap){
|
||||
SqlSession sqlSession = null;
|
||||
List<String> result = new ArrayList<String>();
|
||||
|
||||
try{
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
result = sqlSession.selectList("contractMgmt.getAllSerialNumbersByContract", paramMap);
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
if(sqlSession != null) sqlSession.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서관리 Total 합계 조회
|
||||
* @param request
|
||||
|
||||
@@ -237,7 +237,38 @@ public class SalesNcollectMgmtService {
|
||||
|
||||
return totalsMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 매출관리 합계 조회 (shipment_log 기반)
|
||||
*/
|
||||
public Map<String, Object> getRevenueMgmtTotals(Map<String, Object> paramMap) {
|
||||
SqlSession sqlSession = null;
|
||||
Map<String, Object> totalsMap = new HashMap<String, Object>();
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
totalsMap = sqlSession.selectOne("salesNcollectMgmt.getRevenueMgmtTotals", paramMap);
|
||||
|
||||
if(totalsMap == null) {
|
||||
totalsMap = new HashMap<String, Object>();
|
||||
totalsMap.put("TOTAL_SUPPLY_PRICE", 0);
|
||||
totalsMap.put("TOTAL_VAT", 0);
|
||||
totalsMap.put("TOTAL_AMOUNT", 0);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
totalsMap.put("TOTAL_SUPPLY_PRICE", 0);
|
||||
totalsMap.put("TOTAL_VAT", 0);
|
||||
totalsMap.put("TOTAL_AMOUNT", 0);
|
||||
} finally {
|
||||
if(sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
return totalsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 판매 정보 조회
|
||||
@@ -347,56 +378,68 @@ public List<Map<String, Object>> getProjectItems(Map<String, Object> paramMap) {
|
||||
public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<String, Object> paramMap) {
|
||||
Map<String, Object> resultMap = new HashMap<String, Object>();
|
||||
SqlSession sqlSession = null;
|
||||
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
|
||||
|
||||
PersonBean person = (PersonBean) request.getSession().getAttribute(Constants.PERSON_BEAN);
|
||||
paramMap.put("cretEmpNo", person.getUserId());
|
||||
|
||||
|
||||
String projectNo = (String) paramMap.get("orderNo");
|
||||
String saleNo = (String) paramMap.get("saleNo");
|
||||
|
||||
String logId = (String) paramMap.get("logId");
|
||||
|
||||
System.out.println("=== saveSaleRegistration 시작 ===");
|
||||
System.out.println("projectNo: " + projectNo);
|
||||
System.out.println("saleNo (파라미터): " + saleNo);
|
||||
System.out.println("logId: " + logId);
|
||||
System.out.println("salesQuantity: " + paramMap.get("salesQuantity"));
|
||||
|
||||
// 폼 필드명(manager) → SQL 파라미터명(managerUserId) 매핑
|
||||
|
||||
if(paramMap.get("manager") != null && !"".equals(paramMap.get("manager"))) {
|
||||
paramMap.put("managerUserId", paramMap.get("manager"));
|
||||
}
|
||||
|
||||
System.out.println("serialNo: " + paramMap.get("serialNo"));
|
||||
System.out.println("manager: " + paramMap.get("manager"));
|
||||
|
||||
// saleNo가 있으면 수정 모드 → sales_registration 직접 UPDATE
|
||||
if(saleNo != null && !"".equals(saleNo)) {
|
||||
System.out.println("=== 수정 모드: updateSaleRegistration ===");
|
||||
|
||||
// logId가 있으면 기존 shipment_log 수정
|
||||
if(logId != null && !"".equals(logId)) {
|
||||
System.out.println("=== shipment_log 수정 모드 (logId: " + logId + ") ===");
|
||||
paramMap.put("shippingOrderStatus", "출하지시");
|
||||
sqlSession.update("salesNcollectMgmt.updateSaleRegistration", paramMap);
|
||||
sqlSession.update("salesNcollectMgmt.updateShipmentLog", paramMap);
|
||||
} else {
|
||||
// 신규 등록 모드
|
||||
System.out.println("=== 신규 등록 모드 ===");
|
||||
|
||||
// 1. 해당 프로젝트의 sales_registration 레코드 확인
|
||||
// 신규 등록 → shipment_log에 INSERT
|
||||
System.out.println("=== 신규 출하 등록 → shipment_log INSERT ===");
|
||||
|
||||
// target_objid에 PROJECT_NO를 직접 저장 (기존 데이터와 동일한 형식)
|
||||
Map<String, Object> logParam = new HashMap<String, Object>();
|
||||
logParam.put("targetObjid", projectNo);
|
||||
logParam.put("salesQuantity", paramMap.get("salesQuantity"));
|
||||
logParam.put("originalQuantity", paramMap.get("orderQuantity"));
|
||||
logParam.put("remainingQuantity", paramMap.get("remainingQuantity"));
|
||||
logParam.put("shippingOrderStatus", "출하지시");
|
||||
logParam.put("shippingDate", paramMap.get("shippingDate"));
|
||||
logParam.put("shippingMethod", paramMap.get("shippingMethod"));
|
||||
logParam.put("salesUnitPrice", paramMap.get("salesUnitPrice"));
|
||||
logParam.put("salesSupplyPrice", paramMap.get("salesSupplyPrice"));
|
||||
logParam.put("salesVat", paramMap.get("salesVat"));
|
||||
logParam.put("salesTotalAmount", paramMap.get("salesTotalAmount"));
|
||||
logParam.put("salesCurrency", paramMap.get("salesCurrency"));
|
||||
logParam.put("salesExchangeRate", paramMap.get("salesExchangeRate"));
|
||||
logParam.put("managerUserId", paramMap.get("managerUserId"));
|
||||
logParam.put("incoterms", paramMap.get("incoterms"));
|
||||
logParam.put("serialNo", paramMap.get("serialNo"));
|
||||
logParam.put("parentSaleNo", null);
|
||||
logParam.put("cretEmpNo", paramMap.get("cretEmpNo"));
|
||||
|
||||
sqlSession.insert("salesNcollectMgmt.insertShipmentLog", logParam);
|
||||
System.out.println("shipment_log INSERT 완료");
|
||||
|
||||
// sales_registration이 없으면 기본 레코드 생성
|
||||
Map<String, Object> checkParam = new HashMap<String, Object>();
|
||||
checkParam.put("orderNo", projectNo);
|
||||
Map<String, Object> existingSale = sqlSession.selectOne("salesNcollectMgmt.getSaleInfo", checkParam);
|
||||
|
||||
Object saleNoObj = null;
|
||||
if(existingSale != null) {
|
||||
saleNoObj = existingSale.get("SALE_NO");
|
||||
if(saleNoObj == null) saleNoObj = existingSale.get("sale_no");
|
||||
}
|
||||
|
||||
System.out.println("existingSale: " + (existingSale != null ? "있음" : "없음"));
|
||||
System.out.println("SALE_NO: " + saleNoObj);
|
||||
|
||||
// 2. sales_registration 레코드가 없으면 생성
|
||||
if(saleNoObj == null) {
|
||||
System.out.println("sales_registration 레코드 생성 (첫 판매)");
|
||||
|
||||
Map<String, Object> baseRecord = new HashMap<String, Object>();
|
||||
baseRecord.put("orderNo", projectNo);
|
||||
baseRecord.put("salesQuantity", paramMap.get("salesQuantity"));
|
||||
@@ -408,31 +451,51 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
baseRecord.put("salesExchangeRate", paramMap.get("salesExchangeRate"));
|
||||
baseRecord.put("shippingDate", paramMap.get("shippingDate"));
|
||||
baseRecord.put("shippingMethod", paramMap.get("shippingMethod"));
|
||||
baseRecord.put("managerUserId", paramMap.get("manager"));
|
||||
baseRecord.put("managerUserId", paramMap.get("managerUserId"));
|
||||
baseRecord.put("incoterms", paramMap.get("incoterms"));
|
||||
baseRecord.put("serialNo", paramMap.get("serialNo"));
|
||||
baseRecord.put("shippingOrderStatus", "출하지시");
|
||||
baseRecord.put("cretEmpNo", paramMap.get("cretEmpNo"));
|
||||
|
||||
sqlSession.insert("salesNcollectMgmt.insertSaleRegistration", baseRecord);
|
||||
System.out.println("sales_registration INSERT 완료");
|
||||
} else {
|
||||
// 이미 레코드가 있으면 UPDATE
|
||||
System.out.println("기존 레코드 존재 → updateSaleRegistration");
|
||||
paramMap.put("shippingOrderStatus", "출하지시");
|
||||
sqlSession.update("salesNcollectMgmt.updateSaleRegistration", paramMap);
|
||||
System.out.println("sales_registration INSERT 완료 (첫 판매)");
|
||||
}
|
||||
}
|
||||
|
||||
// S/N → CONTRACT_ITEM_SERIAL 동기화
|
||||
|
||||
// shipment_log 합계로 sales_registration 집계 업데이트 (PROJECT_NO 기준)
|
||||
Map<String, Object> aggParam = new HashMap<String, Object>();
|
||||
aggParam.put("projectNo", projectNo);
|
||||
aggParam.put("managerUserId", paramMap.get("managerUserId"));
|
||||
aggParam.put("incoterms", paramMap.get("incoterms"));
|
||||
aggParam.put("shippingMethod", paramMap.get("shippingMethod"));
|
||||
aggParam.put("shippingDate", paramMap.get("shippingDate"));
|
||||
aggParam.put("salesUnitPrice", paramMap.get("salesUnitPrice"));
|
||||
aggParam.put("salesCurrency", paramMap.get("salesCurrency"));
|
||||
aggParam.put("salesExchangeRate", paramMap.get("salesExchangeRate"));
|
||||
aggParam.put("serialNo", paramMap.get("serialNo"));
|
||||
|
||||
// sale_no 조회
|
||||
Map<String, Object> checkParam2 = new HashMap<String, Object>();
|
||||
checkParam2.put("orderNo", projectNo);
|
||||
Map<String, Object> saleReg = sqlSession.selectOne("salesNcollectMgmt.getSaleInfo", checkParam2);
|
||||
if(saleReg != null) {
|
||||
Object saleNoVal = saleReg.get("SALE_NO");
|
||||
if(saleNoVal == null) saleNoVal = saleReg.get("sale_no");
|
||||
if(saleNoVal != null) {
|
||||
aggParam.put("saleNo", saleNoVal.toString());
|
||||
sqlSession.update("salesNcollectMgmt.updateSalesQuantityFromShipmentLog", aggParam);
|
||||
System.out.println("sales_registration 집계 업데이트 완료");
|
||||
}
|
||||
}
|
||||
|
||||
// S/N → CONTRACT_ITEM_SERIAL 동기화 (S/N은 프로젝트 단위로 동일)
|
||||
String serialNo = CommonUtils.nullToEmpty((String) paramMap.get("serialNo"));
|
||||
String writer = CommonUtils.nullToEmpty((String) paramMap.get("cretEmpNo"));
|
||||
|
||||
|
||||
if(projectNo != null && !projectNo.isEmpty()) {
|
||||
SerialNoSyncUtil.syncSerialToContractItemSerial(
|
||||
sqlSession, projectNo, serialNo, writer);
|
||||
}
|
||||
|
||||
|
||||
sqlSession.commit();
|
||||
resultMap.put("result", true);
|
||||
resultMap.put("msg", "저장되었습니다.");
|
||||
@@ -451,7 +514,7 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@@ -959,12 +1022,12 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
Map resultMap = new HashMap();
|
||||
SqlSession sqlSession = null;
|
||||
try {
|
||||
System.out.println("===== 매출마감 + 아마란스 전표연동 시작 =====");
|
||||
System.out.println("===== 매출마감 + 아마란스 전표연동 시작 (shipment_log 기반) =====");
|
||||
|
||||
String objIdListStr = CommonUtils.checkNull(paramMap.get("objIdList"));
|
||||
String logIdListStr = CommonUtils.checkNull(paramMap.get("logIdList"));
|
||||
String deadlineDate = CommonUtils.checkNull(paramMap.get("deadlineDate"));
|
||||
|
||||
if (objIdListStr == null || objIdListStr.isEmpty()) {
|
||||
if (logIdListStr == null || logIdListStr.isEmpty()) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "선택된 항목이 없습니다.");
|
||||
return resultMap;
|
||||
@@ -975,8 +1038,8 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
String[] targetObjIdList = objIdListStr.split(",");
|
||||
if (targetObjIdList == null || targetObjIdList.length == 0) {
|
||||
String[] targetLogIdList = logIdListStr.split(",");
|
||||
if (targetLogIdList == null || targetLogIdList.length == 0) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "선택된 항목이 없습니다.");
|
||||
return resultMap;
|
||||
@@ -984,39 +1047,36 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
|
||||
// 1) 선택된 항목들의 전표 데이터 조회
|
||||
// 1) 선택된 shipment_log 항목들의 전표 데이터 조회
|
||||
List<Map<String, Object>> slipDataList = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 0; i < targetObjIdList.length; i++) {
|
||||
String objId = CommonUtils.checkNull(targetObjIdList[i]);
|
||||
if (objId.isEmpty()) continue;
|
||||
for (int i = 0; i < targetLogIdList.length; i++) {
|
||||
String logId = CommonUtils.checkNull(targetLogIdList[i]);
|
||||
if (logId.isEmpty()) continue;
|
||||
|
||||
HashMap queryParam = new HashMap();
|
||||
queryParam.put("OBJID", objId);
|
||||
Map<String, Object> slipData = sqlSession.selectOne("salesNcollectMgmt.getSlipDataForDeadline", queryParam);
|
||||
queryParam.put("logId", logId);
|
||||
Map<String, Object> slipData = sqlSession.selectOne("salesNcollectMgmt.getSlipDataForDeadlineByLogId", queryParam);
|
||||
|
||||
if (slipData == null) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "프로젝트 정보를 찾을 수 없습니다. (OBJID: " + objId + ")");
|
||||
resultMap.put("msg", "출하 정보를 찾을 수 없습니다. (LOG_ID: " + logId + ")");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 이미 마감 완료된 건 체크
|
||||
String salesStatus = CommonUtils.checkNull(slipData.get("SALES_STATUS"));
|
||||
if ("완료".equals(salesStatus)) {
|
||||
if (salesStatus != null && !salesStatus.isEmpty()) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "이미 매출마감 완료된 건이 포함되어 있습니다. (" + slipData.get("PROJECT_NO") + ")");
|
||||
resultMap.put("msg", "이미 매출마감 완료된 건이 포함되어 있습니다. (" + slipData.get("PROJECT_NO") + " / LOG_ID: " + logId + ")");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 마감정보 등록 여부 체크
|
||||
String taxType = CommonUtils.checkNull(slipData.get("TAX_TYPE"));
|
||||
if (taxType.isEmpty()) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "마감정보를 먼저 등록해주세요. (" + slipData.get("PROJECT_NO") + ")");
|
||||
resultMap.put("msg", "마감정보를 먼저 등록해주세요. (" + slipData.get("PROJECT_NO") + " / LOG_ID: " + logId + ")");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// ERP 거래처코드 체크
|
||||
String erpClientCd = CommonUtils.checkNull(slipData.get("ERP_CLIENT_CD"));
|
||||
if (erpClientCd.isEmpty()) {
|
||||
resultMap.put("result", false);
|
||||
@@ -1043,7 +1103,7 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
groupByCustomer.get(customerKey).add(data);
|
||||
}
|
||||
|
||||
// 3) DB에서 계정과목 코드 조회 (erp_acct_code → api11A02로 동기화된 값)
|
||||
// 3) DB에서 계정과목 코드 조회
|
||||
SalesSlipApiClient slipApiClient = new SalesSlipApiClient();
|
||||
String erpBaseUrl = "https://erp.rps-korea.com";
|
||||
|
||||
@@ -1064,6 +1124,7 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
);
|
||||
|
||||
int successCount = 0;
|
||||
java.util.Set<String> processedProjects = new java.util.HashSet<String>();
|
||||
|
||||
for (Map.Entry<String, List<Map<String, Object>>> entry : groupByCustomer.entrySet()) {
|
||||
List<Map<String, Object>> customerItems = entry.getValue();
|
||||
@@ -1073,10 +1134,8 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
String customerName = CommonUtils.checkNull(firstItem.get("CUSTOMER_NAME"));
|
||||
String areaCd = CommonUtils.checkNull(firstItem.get("AREA_CD"));
|
||||
String taxType = CommonUtils.checkNull(firstItem.get("TAX_TYPE"));
|
||||
// 국내/해외는 프로젝트의 AREA_CD로 판단, 세무구분(taxFg)은 과세구분(TAX_TYPE)으로 전달
|
||||
boolean isDomestic = "0001220".equals(areaCd);
|
||||
|
||||
// 금액 합산
|
||||
long totalSupplyPrice = 0;
|
||||
long totalVat = 0;
|
||||
long totalAmount = 0;
|
||||
@@ -1091,9 +1150,10 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
|
||||
if (itemNames.length() > 0) itemNames.append(", ");
|
||||
itemNames.append(CommonUtils.checkNull(item.get("PART_NAME")));
|
||||
|
||||
processedProjects.add(CommonUtils.checkNull(item.get("PROJECT_NO")));
|
||||
}
|
||||
|
||||
// 적요: 다건이면 "품명 외 N건"
|
||||
String itemSummary;
|
||||
if (customerItems.size() == 1) {
|
||||
itemSummary = CommonUtils.checkNull(firstItem.get("PART_NAME"));
|
||||
@@ -1101,13 +1161,11 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
itemSummary = CommonUtils.checkNull(firstItem.get("PART_NAME")) + " 외 " + (customerItems.size() - 1) + "건";
|
||||
}
|
||||
|
||||
// 전표 JSON 생성
|
||||
String slipJson;
|
||||
String slipDate;
|
||||
String taxFg = SalesSlipApiClient.convertTaxType(taxType);
|
||||
|
||||
if (isDomestic) {
|
||||
// 국내: 세금계산서발행일 기준
|
||||
String taxInvoiceDate = CommonUtils.checkNull(firstItem.get("TAX_INVOICE_DATE"));
|
||||
slipDate = taxInvoiceDate.replace("-", "");
|
||||
if (slipDate.isEmpty()) {
|
||||
@@ -1117,8 +1175,6 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
}
|
||||
|
||||
String slipTitle = customerName + "_" + itemSummary;
|
||||
|
||||
// 작성번호는 타임스탬프 기반으로 유니크하게 생성
|
||||
int menuSq = generateMenuSq();
|
||||
|
||||
slipJson = slipApiClient.buildDomesticSlipJson(
|
||||
@@ -1128,25 +1184,20 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
itemSummary, taxFg, slipDate
|
||||
);
|
||||
|
||||
// API 호출
|
||||
String apiResponse = slipApiClient.registerSalesSlip(erpBaseUrl, slipJson);
|
||||
System.out.println("[매출마감] 국내 전표 API 응답: " + apiResponse);
|
||||
|
||||
// 응답 검증
|
||||
validateApiResponse(apiResponse, customerName);
|
||||
|
||||
// DB 업데이트: 각 항목에 전표 정보 저장
|
||||
for (Map<String, Object> item : customerItems) {
|
||||
HashMap updateParam = new HashMap();
|
||||
updateParam.put("OBJID", CommonUtils.checkNull(item.get("OBJID")));
|
||||
updateParam.put("logId", CommonUtils.checkNull(item.get("LOG_ID")));
|
||||
updateParam.put("deadlineDate", deadlineDate);
|
||||
updateParam.put("slipDate", slipDate);
|
||||
updateParam.put("slipMenuSq", menuSq);
|
||||
sqlSession.update("salesNcollectMgmt.updateSlipInfo", updateParam);
|
||||
sqlSession.update("salesNcollectMgmt.updateShipmentLogSlipInfo", updateParam);
|
||||
}
|
||||
|
||||
} else {
|
||||
// 해외: 선적일자 기준
|
||||
String loadingDate = CommonUtils.checkNull(firstItem.get("LOADING_DATE"));
|
||||
slipDate = loadingDate.replace("-", "");
|
||||
if (slipDate.isEmpty()) {
|
||||
@@ -1160,7 +1211,7 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
String exportDeclNo = CommonUtils.checkNull(firstItem.get("EXPORT_DECL_NO"));
|
||||
String exchCd = SalesSlipApiClient.convertCurrencyCode(salesCurrency);
|
||||
|
||||
String slipTitle = customerName + "_" + itemSummary
|
||||
String slipTitle = customerName + "_" + itemSummary
|
||||
+ "_" + String.format("%.2f", totalForeignAmount)
|
||||
+ "_@" + String.format("%.2f", exchangeRate);
|
||||
|
||||
@@ -1178,22 +1229,35 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
|
||||
String apiResponse = slipApiClient.registerSalesSlip(erpBaseUrl, slipJson);
|
||||
System.out.println("[매출마감] 해외 전표 API 응답: " + apiResponse);
|
||||
|
||||
validateApiResponse(apiResponse, customerName);
|
||||
|
||||
for (Map<String, Object> item : customerItems) {
|
||||
HashMap updateParam = new HashMap();
|
||||
updateParam.put("OBJID", CommonUtils.checkNull(item.get("OBJID")));
|
||||
updateParam.put("logId", CommonUtils.checkNull(item.get("LOG_ID")));
|
||||
updateParam.put("deadlineDate", deadlineDate);
|
||||
updateParam.put("slipDate", slipDate);
|
||||
updateParam.put("slipMenuSq", menuSq);
|
||||
sqlSession.update("salesNcollectMgmt.updateSlipInfo", updateParam);
|
||||
sqlSession.update("salesNcollectMgmt.updateShipmentLogSlipInfo", updateParam);
|
||||
}
|
||||
}
|
||||
|
||||
successCount += customerItems.size();
|
||||
}
|
||||
|
||||
// 프로젝트별 전체 마감 여부 확인 → 모든 출하건 마감 시 PROJECT_MGMT도 '완료' 처리
|
||||
for (String projectNo : processedProjects) {
|
||||
HashMap checkParam = new HashMap();
|
||||
checkParam.put("projectNo", projectNo);
|
||||
int unclosedCount = (Integer) sqlSession.selectOne("salesNcollectMgmt.checkAllShipmentLogClosed", checkParam);
|
||||
if (unclosedCount == 0) {
|
||||
HashMap pmUpdateParam = new HashMap();
|
||||
pmUpdateParam.put("projectNo", projectNo);
|
||||
pmUpdateParam.put("deadlineDate", deadlineDate);
|
||||
sqlSession.update("salesNcollectMgmt.updateProjectSalesStatus", pmUpdateParam);
|
||||
System.out.println("[매출마감] 프로젝트 전체 마감 완료: " + projectNo);
|
||||
}
|
||||
}
|
||||
|
||||
sqlSession.commit();
|
||||
resultMap.put("result", true);
|
||||
resultMap.put("msg", successCount + "건의 매출마감이 완료되었습니다. (전표 " + groupByCustomer.size() + "건 등록)");
|
||||
@@ -1388,7 +1452,33 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* shipment_log 단건 조회 (수정 팝업용)
|
||||
* @param logId
|
||||
* @return Map
|
||||
*/
|
||||
public Map<String, Object> getShipmentLogById(String logId) {
|
||||
SqlSession sqlSession = null;
|
||||
Map<String, Object> result = null;
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
Map<String, Object> paramMap = new HashMap<String, Object>();
|
||||
paramMap.put("logId", logId);
|
||||
result = sqlSession.selectOne("salesNcollectMgmt.getShipmentLogById", paramMap);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
if(result != null) {
|
||||
result = CommonUtils.toUpperCaseMapKey(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 거래명세서 데이터 조회
|
||||
* @param paramMap - projectNos (쉼표로 구분된 프로젝트 번호들)
|
||||
@@ -1716,43 +1806,43 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
*/
|
||||
public Map saveDeadlineInfo(HttpServletRequest request, Map paramMap) {
|
||||
Map resultMap = new HashMap();
|
||||
SqlSession sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
SqlSession sqlSession = null;
|
||||
try {
|
||||
String objIdListStr = CommonUtils.checkNull(paramMap.get("objIdList"));
|
||||
String logIdListStr = CommonUtils.checkNull(paramMap.get("logIdList"));
|
||||
String taxType = CommonUtils.checkNull(paramMap.get("taxType"));
|
||||
String taxInvoiceDate = CommonUtils.checkNull(paramMap.get("taxInvoiceDate"));
|
||||
String exportDeclNo = CommonUtils.checkNull(paramMap.get("exportDeclNo"));
|
||||
String loadingDate = CommonUtils.checkNull(paramMap.get("loadingDate"));
|
||||
|
||||
if (objIdListStr == null || objIdListStr.isEmpty()) {
|
||||
if (logIdListStr == null || logIdListStr.isEmpty()) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "선택된 항목이 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
String[] targetObjIdList = objIdListStr.split(",");
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
String[] targetLogIdList = logIdListStr.split(",");
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
|
||||
for (int i = 0; i < targetObjIdList.length; i++) {
|
||||
for (int i = 0; i < targetLogIdList.length; i++) {
|
||||
HashMap sqlParamMap = new HashMap();
|
||||
sqlParamMap.put("OBJID", CommonUtils.checkNull(targetObjIdList[i]));
|
||||
sqlParamMap.put("logId", CommonUtils.checkNull(targetLogIdList[i]));
|
||||
sqlParamMap.put("taxType", taxType);
|
||||
sqlParamMap.put("taxInvoiceDate", taxInvoiceDate);
|
||||
sqlParamMap.put("exportDeclNo", exportDeclNo);
|
||||
sqlParamMap.put("loadingDate", loadingDate);
|
||||
|
||||
sqlSession.update("salesNcollectMgmt.saveDeadlineInfo", sqlParamMap);
|
||||
sqlSession.update("salesNcollectMgmt.saveShipmentLogDeadlineInfo", sqlParamMap);
|
||||
}
|
||||
sqlSession.commit();
|
||||
resultMap.put("result", true);
|
||||
resultMap.put("msg", targetObjIdList.length + "건의 마감정보가 저장되었습니다.");
|
||||
resultMap.put("msg", targetLogIdList.length + "건의 마감정보가 저장되었습니다.");
|
||||
} catch (Exception e) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "마감정보 저장 중 오류가 발생했습니다.");
|
||||
sqlSession.rollback();
|
||||
if (sqlSession != null) sqlSession.rollback();
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
sqlSession.close();
|
||||
if (sqlSession != null) sqlSession.close();
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@@ -776,21 +776,17 @@ public class BatchService extends BaseService {
|
||||
System.out.println("====================================");
|
||||
|
||||
for (Map<String, Object> emp : empList) {
|
||||
// 처음 10건만 로그 출력
|
||||
if (processCount < 10) {
|
||||
System.out.println("[사원 " + (processCount + 1) + "]");
|
||||
System.out.println(" - USER_ID: " + emp.get("user_id"));
|
||||
System.out.println(" - SABUN: " + emp.get("sabun"));
|
||||
System.out.println(" - USER_NAME: " + emp.get("user_name"));
|
||||
System.out.println(" - USER_NAME_ENG: " + emp.get("user_name_eng"));
|
||||
System.out.println(" - DEPT_CODE: " + emp.get("dept_code"));
|
||||
System.out.println(" - DEPT_NAME: " + emp.get("dept_name"));
|
||||
System.out.println(" - EMAIL: " + emp.get("email"));
|
||||
System.out.println(" - CELL_PHONE: " + emp.get("cell_phone"));
|
||||
System.out.println(" - STATUS: " + emp.get("status"));
|
||||
System.out.println(" - TEL: " + emp.get("tel"));
|
||||
System.out.println("---");
|
||||
}
|
||||
|
||||
// UPSERT 실행
|
||||
|
||||
sqlSession.insert("batch.upsertEmployee", emp);
|
||||
processCount++;
|
||||
}
|
||||
@@ -1314,7 +1310,13 @@ public class BatchService extends BaseService {
|
||||
emp.put("position_code", extractJsonValue(json, "hclsCd")); // 직급코드 (hclsCd)
|
||||
emp.put("position_name", extractJsonValue(json, "hclsNm")); // 직급명 (hclsNm)
|
||||
emp.put("rank", extractJsonValue(json, "hrspNm")); // 직책명 (hrspNm - 사원, 대리 등)
|
||||
emp.put("email", extractJsonValue(json, "emalAdd")); // 이메일 (emalAdd)
|
||||
// 이메일: 급여이메일(emalAdd) 우선, 없으면 외부이메일(outemalAdd) 사용
|
||||
String email = extractJsonValue(json, "emalAdd");
|
||||
if (email == null || email.isEmpty()) {
|
||||
email = extractJsonValue(json, "outemalAdd");
|
||||
}
|
||||
emp.put("email", email);
|
||||
emp.put("tel", extractJsonValue(json, "tel")); // 전화번호 (tel)
|
||||
emp.put("cell_phone", extractJsonValue(json, "emgcTel")); // 휴대폰 (emgcTel)
|
||||
emp.put("user_type", extractJsonValue(json, "enrlFg")); // 사용자유형 (enrlFg - J01:재직)
|
||||
emp.put("user_type_name", extractJsonValue(json, "enrlNm")); // 사용자유형명 (enrlNm)
|
||||
|
||||
Reference in New Issue
Block a user