350 lines
11 KiB
Plaintext
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>
|
|
|