판매관리 검색조건 추가(판매상태 다중선택)

This commit is contained in:
2026-01-28 13:28:05 +09:00
parent 8c287e714c
commit 6fcc27bd37
4 changed files with 180 additions and 137 deletions

View File

@@ -19,6 +19,26 @@
margin: 0;
padding: 0;
}
/* 판매상태 멀티선택 높이 조정 */
#salesStatus + .select2-container {
min-height: 25px !important;
max-height: 25px !important;
}
#salesStatus + .select2-container .select2-selection--multiple {
min-height: 25px !important;
max-height: 25px !important;
padding: 0 5px;
overflow: hidden;
}
#salesStatus + .select2-container .select2-selection__choice {
margin-top: 2px;
padding: 0 5px;
font-size: 11px;
}
#salesStatus + .select2-container .select2-search--inline .select2-search__field {
margin-top: 3px;
font-size: 11px;
}
</style>
<script>
@@ -390,7 +410,9 @@ var columns = [
},
// 18. 수주상태
{headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '수주상태', field : 'ORDER_STATUS'},
// 19. 생산상태
// 19. 판매상태
{headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '판매상태', field : 'SALES_STATUS'},
// 20. 생산상태
{headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '생산상태', field : 'PRODUCTION_STATUS'},
// 20. 출하지시상태
{headerHozAlign : 'center', hozAlign : 'center', width : '90', title : '출하지시상태', field : 'SHIPPING_ORDER_STATUS'},
@@ -453,11 +475,12 @@ columns = fnc_applyHeaderAutoWidth(columns);
// 데이터 조회 함수
function fn_search(){
// 디버깅: 검색 파라미터 확인
var formData = $("#form1").serializeObject();
var formData = $("#form1").serialize();
// 판매상태 멀티선택 값 별도 추가 (serialize는 multiple select를 제대로 처리함)
var salesStatusValues = $("#salesStatus").val();
console.log("=== 판매관리 조회 파라미터 ===");
console.log("search_partObjId:", formData.search_partObjId);
console.log("search_partNo:", formData.search_partNo);
console.log("search_partName:", formData.search_partName);
console.log("salesStatus 선택값:", salesStatusValues);
console.log("전체 파라미터:", formData);
// 그리드 조회 및 Total 합계 업데이트를 위한 커스텀 AJAX
@@ -694,119 +717,80 @@ body {
</div>
</div>
<div id="plmSearchZon">
<!-- 검색필터: 주문유형, 발주번호, 고객사, 품번, 품명, S/N, 출하지시상태, 발주일(기간), 출하일(기간) -->
<div style="display: flex; flex-wrap: wrap; gap: 10px 15px; align-items: center;">
<!-- 주문유형 -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>주문유형</label>
<select name="orderType" class="select2" style="width:120px;"><option value="">전체</option>${codeMap.orderTypeList}</select>
</div>
<!-- 발주번호 -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>발주번호</label>
<input type="text" name="poNo" style="width:100px;"/>
</div>
<!-- 고객사 -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>고객사</label>
<select name="customer_objid" id="customer_objid" style="width:150px" class="select2">
<option value="">전체</option>
${codeMap.customer_cd}
</select>
</div>
<!-- 품번 -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>품번</label>
<select name="search_partNo" id="search_partNo" class="select2-part" style="width: 120px;">
<option value="">품번 선택</option>
</select>
<input type="hidden" name="search_partObjId" id="search_partObjId" value=""/>
</div>
<!-- 품명 -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>품명</label>
<select name="search_partName" id="search_partName" class="select2-part" style="width: 120px;">
<option value="">품명 선택</option>
</select>
</div>
<!-- S/N -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>S/N</label>
<input type="text" name="serialNo" style="width:100px;"/>
</div>
<!-- 출하지시상태 -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>출하지시상태</label>
<select name="shippingStatus" class="select2" style="width:120px;"><option value="">전체</option>${codeMap.shippingStatusList}</select>
</div>
<!-- 발주일 (기간) -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>발주일</label>
<input type="text" name="orderDateFrom" class="date_icon" style="width:90px;"/> ~
<input type="text" name="orderDateTo" class="date_icon" style="width:90px;"/>
</div>
<!-- 출하일 (기간) -->
<div style="display: flex; align-items: center; gap: 5px;">
<label>출하일</label>
<input type="text" name="shippingDateFrom" class="date_icon" style="width:90px;"/> ~
<input type="text" name="shippingDateTo" class="date_icon" style="width:90px;"/>
</div>
</div>
<table>
<tr>
<td><label for="orderType">주문유형</label></td>
<td>
<select name="orderType" id="orderType" style="width:120px" class="select2" autocomplete="off">
<option value="">전체</option>
${codeMap.orderTypeList}
</select>
</td>
<td><label for="poNo">발주번호</label></td>
<td>
<input type="text" name="poNo" id="poNo" style="width:120px">
</td>
<td><label for="customer_objid">고객사</label></td>
<td>
<select name="customer_objid" id="customer_objid" style="width:230px" class="select2" autocomplete="off">
<option value="">전체</option>
${codeMap.customer_cd}
</select>
</td>
<td><label for="search_partNo">품번</label></td>
<td>
<select name="search_partNo" id="search_partNo" class="select2-part" style="width:150px">
<option value="">품번 입력하여 검색...</option>
</select>
<input type="hidden" name="search_partObjId" id="search_partObjId" value="">
</td>
<td><label for="search_partName">품명</label></td>
<td>
<select name="search_partName" id="search_partName" class="select2-part" style="width:150px">
<option value="">품명 입력하여 검색...</option>
</select>
</td>
<td><label for="serialNo">S/N</label></td>
<td>
<input type="text" name="serialNo" id="serialNo" style="width:100px">
</td>
<td><label for="shippingStatus">출하지시상태</label></td>
<td>
<select name="shippingStatus" id="shippingStatus" style="width:120px" class="select2" autocomplete="off">
<option value="">전체</option>
${codeMap.shippingStatusList}
</select>
</td>
</tr>
<tr>
<td><label for="orderDateFrom">발주일</label></td>
<td>
<input type="text" name="orderDateFrom" id="orderDateFrom" autocomplete="off" class="date_icon" style="width:100px">~
<input type="text" name="orderDateTo" id="orderDateTo" autocomplete="off" class="date_icon" style="width:100px">
</td>
<td><label for="shippingDateFrom">출하일</label></td>
<td>
<input type="text" name="shippingDateFrom" id="shippingDateFrom" autocomplete="off" class="date_icon" style="width:100px">~
<input type="text" name="shippingDateTo" id="shippingDateTo" autocomplete="off" class="date_icon" style="width:100px">
</td>
<td><label for="salesStatus">판매상태</label></td>
<td>
<select name="salesStatus" id="salesStatus" style="width:230px; height:25px;" class="select2" multiple="multiple" autocomplete="off">
${codeMap.salesStatusList}
</select>
</td>
</tr>
</table>
</div>
<!-- 주석처리된 검색필터 - 필요시 활성화
<div style="display: flex; align-items: center; gap: 5px;">
<label>제품구분</label>
<select name="productType" class="select2" style="width:120px;"><option value="">전체</option>${codeMap.productTypeList}</select>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>국내/해외</label>
<select name="nation" class="select2" style="width:100px;">
<option value="">전체</option>
<option value="0001220">국내</option>
<option value="0001221">해외</option>
</select>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>유/무상</label>
<select name="paymentType" class="select2" style="width:90px;">
<option value="">전체</option>
<option value="paid">유상</option>
<option value="free">무상</option>
</select>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>수주상태</label>
<select name="orderStatus" class="select2" style="width:120px;"><option value="">전체</option>${codeMap.orderStatusList}</select>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>요청납기</label>
<input type="text" name="requestDateFrom" class="date_icon" style="width:90px;"/> ~
<input type="text" name="requestDateTo" class="date_icon" style="width:90px;"/>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>출고방법</label>
<select name="shippingMethod" class="select2" style="width:100px;">
<option value="">전체</option>
<option value="DIRECT">직납</option>
<option value="PARCEL">택배</option>
</select>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>담당자</label>
<select name="manager" class="select2" style="width:120px;"><option value="">전체</option>${codeMap.managerList}</select>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>인도조건</label>
<select name="incoterms" class="select2" style="width:100px;">
<option value="">전체</option>
<option value="EXW">EXW</option>
<option value="FOB">FOB</option>
<option value="CIF">CIF</option>
<option value="DDP">DDP</option>
</select>
</div>
-->
<!-- Total 합계 표시 영역 (판매원화총액 기준) -->
<div style="padding:5px 10px; background: #f5f5f5;">

View File

@@ -2689,7 +2689,7 @@ INSERT INTO OEM_MNG
VALUES
(
#{objid}::numeric,
LPAD(nextval('seq_comm_code')::varchar,7,'0'),
LPAD((COALESCE((SELECT MAX(CODE_ID::numeric) FROM COMM_CODE WHERE CODE_ID ~ '^[0-9]+$'), 0) + 1)::varchar, 7, '0'),
#{parentCodeId},
#{codeName},
#{id},

View File

@@ -10,6 +10,7 @@
package com.pms.salesmgmt.controller;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -188,6 +189,8 @@ public class SalesNcollectMgmtController {
codeMap.put("shippingStatusList", shippingStatusOptions.toString());
// 담당자
codeMap.put("managerList", commonService.bizMakeOptionList("", "", "common.getUserselect"));
// 판매상태 - 0900207
codeMap.put("salesStatusList", commonService.bizMakeOptionList("0900207", "", "common.getCodeselect"));
request.setAttribute("codeMap", codeMap);
} catch (Exception e) {
@@ -447,6 +450,28 @@ public class SalesNcollectMgmtController {
System.out.println("poNo: [" + paramMap.get("poNo") + "]");
System.out.println("serialNo: [" + paramMap.get("serialNo") + "]");
// 판매상태 멀티 선택 처리 (배열 → 리스트 변환)
String[] salesStatusArr = request.getParameterValues("salesStatus");
System.out.println("=== 판매상태 파라미터 디버깅 ===");
System.out.println("salesStatusArr: " + (salesStatusArr != null ? java.util.Arrays.toString(salesStatusArr) : "null"));
if(salesStatusArr != null && salesStatusArr.length > 0) {
List<String> salesStatusList = new ArrayList<String>();
for(String status : salesStatusArr) {
System.out.println(" status 값: [" + status + "]");
if(status != null && !status.isEmpty()) {
salesStatusList.add(status);
}
}
System.out.println("salesStatusList: " + salesStatusList);
if(!salesStatusList.isEmpty()) {
paramMap.put("salesStatus", salesStatusList);
} else {
paramMap.remove("salesStatus");
}
} else {
paramMap.remove("salesStatus");
}
// 품명/품번 파라미터가 비어있으면 경고
if((paramMap.get("search_partNo") == null || paramMap.get("search_partNo").toString().isEmpty()) &&
(paramMap.get("search_partName") == null || paramMap.get("search_partName").toString().isEmpty())) {

View File

@@ -926,7 +926,17 @@
(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = T.PM_USER_ID)
) AS MANAGER,
COALESCE(SR.incoterms, '') AS INCOTERMS,
T.SALES_STATUS,
-- 판매상태: 수주수량과 판매수량 비교하여 동적 계산
CASE
WHEN COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) = 0
THEN '미판매'
WHEN COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) >= COALESCE(T.QUANTITY::numeric, 0)
THEN '완판'
WHEN COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) > 0
AND COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) <![CDATA[<]]> COALESCE(T.QUANTITY::numeric, 0)
THEN '분할판매'
ELSE ''
END AS SALES_STATUS,
T.OBJID::VARCHAR AS SALE_NO,
'ORIGINAL' AS RECORD_TYPE,
'' AS SPLIT_LOG_ID,
@@ -1069,15 +1079,27 @@
AND SR.project_no IS NOT NULL
AND SR.incoterms = #{incoterms}
</if>
<if test="salesStatus != null and salesStatus != ''">
<choose>
<when test="salesStatus == 'NOT_CLOSED'">
AND (T.SALES_STATUS IS NULL OR T.SALES_STATUS = '' OR T.SALES_STATUS != '완료')
</when>
<otherwise>
AND T.SALES_STATUS = #{salesStatus}
</otherwise>
</choose>
<!-- 판매상태 검색 (멀티 선택 지원) - 동적 계산 기준 -->
<if test="salesStatus != null and salesStatus.size() > 0">
AND (
1=0
<foreach item="item" collection="salesStatus">
<!-- 완판: 0900208 -->
<if test="'0900208'.equals(item)">
OR (COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) >= COALESCE(T.QUANTITY::numeric, 0)
AND COALESCE(T.QUANTITY::numeric, 0) > 0)
</if>
<!-- 분할판매: 0900209 -->
<if test="'0900209'.equals(item)">
OR (COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) > 0
AND COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) <![CDATA[<]]> COALESCE(T.QUANTITY::numeric, 0))
</if>
<!-- 미판매: 0900210 -->
<if test="'0900210'.equals(item)">
OR COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) = 0
</if>
</foreach>
)
</if>
<!-- 매출마감 기간 검색 -->
<if test="salesDeadlineFrom != null and salesDeadlineFrom != ''">
@@ -1248,15 +1270,27 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
AND SR.incoterms = #{incoterms}
)
</if>
<if test="salesStatus != null and salesStatus != ''">
<choose>
<when test="salesStatus == 'NOT_CLOSED'">
AND (T.SALES_STATUS IS NULL OR T.SALES_STATUS = '' OR T.SALES_STATUS != '완료')
</when>
<otherwise>
AND T.SALES_STATUS = #{salesStatus}
</otherwise>
</choose>
<!-- 판매상태 검색 (멀티 선택 지원) - 동적 계산 기준 -->
<if test="salesStatus != null and salesStatus.size() > 0">
AND (
1=0
<foreach item="item" collection="salesStatus">
<!-- 완판: 0900208 -->
<if test="'0900208'.equals(item)">
OR (COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) >= COALESCE(T.QUANTITY::numeric, 0)
AND COALESCE(T.QUANTITY::numeric, 0) > 0)
</if>
<!-- 분할판매: 0900209 -->
<if test="'0900209'.equals(item)">
OR (COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) > 0
AND COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) <![CDATA[<]]> COALESCE(T.QUANTITY::numeric, 0))
</if>
<!-- 미판매: 0900210 -->
<if test="'0900210'.equals(item)">
OR COALESCE((SELECT SUM(sales_quantity) FROM sales_registration WHERE project_no LIKE T.PROJECT_NO || '%'), 0) = 0
</if>
</foreach>
)
</if>
<!-- 매출마감 기간 검색 -->
<if test="salesDeadlineFrom != null and salesDeadlineFrom != ''">