Files
wace_plm/WebContent/WEB-INF/view/contractMgmt/itemPriceCompareList.jsp
2025-12-03 17:19:22 +09:00

350 lines
11 KiB
Plaintext

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.pms.common.utils.*"%>
<%@ page import="java.util.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@include file="/init.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<c:set var="now" value="<%=new java.util.Date() %>"/>
<c:set var="sysYear"><fmt:formatDate value="${now}" pattern="yyyy" /></c:set>
<style>
body {
overflow-x: hidden !important;
}
.price-table-container {
margin-top: 15px;
overflow-x: auto;
}
/* Tabulator 커스텀 스타일 */
.tabulator .tabulator-header .tabulator-col.estimate-col {
background-color: #d4edda !important;
}
.tabulator .tabulator-header .tabulator-col.order-col {
background-color: #cce5ff !important;
}
.tabulator .tabulator-header .tabulator-col.sales-col {
background-color: #fff3cd !important;
}
.tabulator-row .tabulator-cell.estimate-cell {
background-color: #f0fff0;
}
.tabulator-row .tabulator-cell.order-cell {
background-color: #f0f8ff;
}
.tabulator-row .tabulator-cell.sales-cell {
background-color: #fffef0;
}
.price-up {
color: #28a745;
font-weight: bold;
}
.price-down {
color: #dc3545;
font-weight: bold;
}
.price-same {
color: #6c757d;
}
/* 요약 카드 스타일 */
.summary-cards {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.summary-card {
flex: 1;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.summary-card.estimate {
background: linear-gradient(135deg, #d4edda, #c3e6cb);
border-left: 4px solid #28a745;
}
.summary-card.order {
background: linear-gradient(135deg, #cce5ff, #b8daff);
border-left: 4px solid #007bff;
}
.summary-card.sales {
background: linear-gradient(135deg, #fff3cd, #ffeeba);
border-left: 4px solid #ffc107;
}
.summary-card h4 {
margin: 0 0 10px 0;
font-size: 14px;
color: #333;
}
.summary-card .amount {
font-size: 24px;
font-weight: bold;
color: #333;
}
.summary-card .count {
font-size: 12px;
color: #666;
margin-top: 5px;
}
</style>
<script type="text/javascript">
var _tabulGrid;
$(function(){
// 조회 버튼
$("#btnSearch").click(function(){
fn_search();
});
// 초기화 버튼
$("#btnReset").click(function(){
$("#form1")[0].reset();
$(".select2").val("").trigger("change");
});
// 엔터 조회
$("input").keyup(function(e){
if(e.keyCode == 13){
fn_search();
}
});
// 그리드 초기화
_tabulGrid = new Tabulator("#grid", {
height: "calc(100vh - 350px)",
layout: "fitColumns",
placeholder: "조회된 데이터가 없습니다.",
selectable: 1,
columns: [
// 기본 정보
{title: "No", field: "ROWNUM", hozAlign: "center", width: 50, frozen: true},
{title: "영업번호", field: "CONTRACT_NO", hozAlign: "center", minWidth: 100, frozen: true},
{title: "프로젝트번호", field: "PROJECT_NO", hozAlign: "center", minWidth: 120},
{title: "고객사", field: "CUSTOMER_NAME", hozAlign: "left", minWidth: 100},
{title: "품번", field: "PART_NO", hozAlign: "center", minWidth: 100},
{title: "품명", field: "PART_NAME", hozAlign: "left", minWidth: 120},
// 견적 정보
{title: "견적수량", field: "EST_QUANTITY", hozAlign: "right", minWidth: 70, cssClass: "estimate-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "견적단가", field: "EST_UNIT_PRICE", hozAlign: "right", minWidth: 80, cssClass: "estimate-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "견적공급가", field: "EST_SUPPLY_PRICE", hozAlign: "right", minWidth: 90, cssClass: "estimate-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "견적합계", field: "EST_TOTAL_AMOUNT", hozAlign: "right", minWidth: 90, cssClass: "estimate-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
// 수주 정보
{title: "수주수량", field: "ORDER_QUANTITY", hozAlign: "right", minWidth: 70, cssClass: "order-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "수주단가", field: "ORDER_UNIT_PRICE", hozAlign: "right", minWidth: 80, cssClass: "order-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "수주공급가", field: "ORDER_SUPPLY_PRICE", hozAlign: "right", minWidth: 90, cssClass: "order-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "수주합계", field: "ORDER_TOTAL_AMOUNT", hozAlign: "right", minWidth: 90, cssClass: "order-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
// 판매 정보
{title: "판매수량", field: "SALES_QUANTITY", hozAlign: "right", minWidth: 70, cssClass: "sales-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "판매단가", field: "SALES_UNIT_PRICE", hozAlign: "right", minWidth: 80, cssClass: "sales-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "판매공급가", field: "SALES_SUPPLY_PRICE", hozAlign: "right", minWidth: 90, cssClass: "sales-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
{title: "판매합계", field: "SALES_TOTAL_AMOUNT", hozAlign: "right", minWidth: 90, cssClass: "sales-cell",
formatter: function(cell) { return formatNumber(cell.getValue()); }
},
// 비교
{title: "견적→수주", field: "EST_TO_ORDER_DIFF", hozAlign: "center", minWidth: 80,
formatter: function(cell) {
var diff = cell.getValue();
if(diff > 0) return '<span class="price-up">↑ ' + formatNumber(diff) + '</span>';
if(diff < 0) return '<span class="price-down">↓ ' + formatNumber(Math.abs(diff)) + '</span>';
return '<span class="price-same">=</span>';
}
},
{title: "수주→판매", field: "ORDER_TO_SALES_DIFF", hozAlign: "center", minWidth: 80,
formatter: function(cell) {
var diff = cell.getValue();
if(diff > 0) return '<span class="price-up">↑ ' + formatNumber(diff) + '</span>';
if(diff < 0) return '<span class="price-down">↓ ' + formatNumber(Math.abs(diff)) + '</span>';
return '<span class="price-same">=</span>';
}
}
]
});
// 초기 조회
fn_search();
});
// 숫자 포맷
function formatNumber(num) {
if(num == null || num == '' || isNaN(num) || num == 0) return '-';
return parseFloat(num).toLocaleString('ko-KR');
}
// 조회
function fn_search() {
var params = {
contract_no: $("#contract_no").val(),
project_no: $("#project_no").val(),
customer_name: $("#customer_name").val(),
part_no: $("#part_no").val(),
part_name: $("#part_name").val(),
from_date: $("#from_date").val(),
to_date: $("#to_date").val()
};
$.ajax({
url: "/contractMgmt/getItemPriceCompareGridList.do",
type: "POST",
data: params,
dataType: "json",
success: function(data) {
if(data && data.list) {
_tabulGrid.setData(data.list);
// 요약 정보 업데이트
updateSummary(data.summary);
} else {
_tabulGrid.setData([]);
updateSummary(null);
}
},
error: function(xhr, status, error) {
console.error("조회 오류:", error);
Swal.fire("조회 중 오류가 발생했습니다.");
}
});
}
// 요약 정보 업데이트
function updateSummary(summary) {
if(summary) {
$("#estTotalAmount").text(formatNumber(summary.totalEstAmount) || '-');
$("#estCount").text((summary.estCount || 0) + '건');
$("#orderTotalAmount").text(formatNumber(summary.totalOrderAmount) || '-');
$("#orderCount").text((summary.orderCount || 0) + '건');
$("#salesTotalAmount").text(formatNumber(summary.totalSalesAmount) || '-');
$("#salesCount").text((summary.salesCount || 0) + '건');
} else {
$("#estTotalAmount, #orderTotalAmount, #salesTotalAmount").text('-');
$("#estCount, #orderCount, #salesCount").text('0건');
}
}
</script>
</head>
<body class="bodyNoScroll">
<form name="form1" id="form1" method="post">
<div class="min_part_enroll">
<div class="content-box">
<div class="content-box-s">
<div class="plm_menu_name_gdnsi">
<h2>
<span>영업관리_품목별 가격비교</span>
</h2>
<div class="btnArea">
<input type="button" value="조회" class="plm_btns" id="btnSearch">
<input type="button" value="초기화" class="plm_btns" id="btnReset">
</div>
</div>
<!-- 검색 필터 -->
<div id="plmSearchZon">
<div style="display: flex; flex-wrap: wrap; gap: 10px 15px; align-items: center;">
<div style="display: flex; align-items: center; gap: 5px;">
<label for="contract_no">영업번호</label>
<input type="text" id="contract_no" name="contract_no" style="width:120px;">
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label for="project_no">프로젝트번호</label>
<input type="text" id="project_no" name="project_no" style="width:130px;">
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label for="customer_name">고객사</label>
<input type="text" id="customer_name" name="customer_name" style="width:100px;">
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label for="part_no">품번</label>
<input type="text" id="part_no" name="part_no" style="width:100px;">
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label for="part_name">품명</label>
<input type="text" id="part_name" name="part_name" style="width:100px;">
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<label>기간</label>
<input type="date" id="from_date" name="from_date" style="width:130px;">
<span>~</span>
<input type="date" id="to_date" name="to_date" style="width:130px;">
</div>
</div>
</div>
<!-- 요약 카드 -->
<div class="summary-cards">
<div class="summary-card estimate">
<h4>📋 견적 합계</h4>
<div class="amount" id="estTotalAmount">-</div>
<div class="count" id="estCount">0건</div>
</div>
<div class="summary-card order">
<h4>📝 수주 합계</h4>
<div class="amount" id="orderTotalAmount">-</div>
<div class="count" id="orderCount">0건</div>
</div>
<div class="summary-card sales">
<h4>💰 판매 합계</h4>
<div class="amount" id="salesTotalAmount">-</div>
<div class="count" id="salesCount">0건</div>
</div>
</div>
<!-- 그리드 -->
<div class="price-table-container">
<div id="grid"></div>
</div>
</div>
</div>
</div>
</form>
</body>
</html>