176 lines
7.7 KiB
Java
176 lines
7.7 KiB
Java
package com.erp.service;
|
|
|
|
import com.erp.common.BaseService;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.*;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class CascadingMutualExclusionService extends BaseService {
|
|
|
|
private static final String NS = "cascadingMutualExclusion.";
|
|
|
|
private final CommonService commonService;
|
|
private final JdbcTemplate jdbcTemplate;
|
|
|
|
public Map<String, Object> getCascadingMutualExclusionList(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
commonService.applyPagination(params);
|
|
int totalCount = sqlSession.selectOne(NS + "getCascadingMutualExclusionListCnt", params);
|
|
List<Map<String, Object>> list = sqlSession.selectList(NS + "getCascadingMutualExclusionList", params);
|
|
return commonService.buildListResponse(list, totalCount, params);
|
|
}
|
|
|
|
public Map<String, Object> getCascadingMutualExclusionInfo(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
return sqlSession.selectOne(NS + "getCascadingMutualExclusionInfo", params);
|
|
}
|
|
|
|
@Transactional
|
|
public Map<String, Object> insertCascadingMutualExclusion(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
if (params.get("exclusion_type") == null) params.put("exclusion_type", "SAME_VALUE");
|
|
if (params.get("error_message") == null) params.put("error_message", "동일한 값을 선택할 수 없습니다");
|
|
|
|
// 배제 코드 자동 생성: EX_XXXX_NNN
|
|
String companyCode = (String) params.get("company_code");
|
|
Map<String, Object> countParams = new LinkedHashMap<>();
|
|
countParams.put("company_code", companyCode);
|
|
int count = sqlSession.selectOne(NS + "getCascadingMutualExclusionCount", countParams);
|
|
String ts = Long.toString(System.currentTimeMillis(), 36).toUpperCase();
|
|
ts = ts.substring(Math.max(0, ts.length() - 4));
|
|
params.put("exclusion_code", String.format("EX_%s_%03d", ts, count + 1));
|
|
|
|
sqlSession.insert(NS + "insertCascadingMutualExclusion", params);
|
|
return params;
|
|
}
|
|
|
|
@Transactional
|
|
public Map<String, Object> updateCascadingMutualExclusion(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
sqlSession.update(NS + "updateCascadingMutualExclusion", params);
|
|
return params;
|
|
}
|
|
|
|
@Transactional
|
|
public Map<String, Object> deleteCascadingMutualExclusion(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
sqlSession.delete(NS + "deleteCascadingMutualExclusion", params);
|
|
return params;
|
|
}
|
|
|
|
/**
|
|
* 상호 배제 검증: 선택한 값들 간 충돌 여부 확인 (SAME_VALUE 타입)
|
|
*/
|
|
public Map<String, Object> validateCascadingMutualExclusion(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
Map<String, Object> exclusion = sqlSession.selectOne(NS + "getCascadingMutualExclusionByCode", params);
|
|
if (exclusion == null) throw new NoSuchElementException("상호 배제 규칙을 찾을 수 없습니다.");
|
|
|
|
@SuppressWarnings("unchecked")
|
|
Map<String, Object> fieldValues = (Map<String, Object>) params.getOrDefault("field_values", Collections.emptyMap());
|
|
|
|
String fieldNamesStr = (String) exclusion.get("field_names");
|
|
String[] fields = fieldNamesStr != null ? fieldNamesStr.split(",") : new String[0];
|
|
|
|
List<String> values = new ArrayList<>();
|
|
for (String field : fields) {
|
|
Object v = fieldValues.get(field.trim());
|
|
if (v != null) values.add(v.toString());
|
|
}
|
|
|
|
boolean isValid = true;
|
|
String errorMessage = null;
|
|
List<String> conflictingFields = new ArrayList<>();
|
|
|
|
String exclusionType = (String) exclusion.getOrDefault("exclusion_type", "SAME_VALUE");
|
|
if ("SAME_VALUE".equals(exclusionType)) {
|
|
Set<String> seen = new LinkedHashSet<>();
|
|
boolean hasDuplicate = false;
|
|
for (String v : values) {
|
|
if (!seen.add(v)) { hasDuplicate = true; break; }
|
|
}
|
|
if (hasDuplicate) {
|
|
isValid = false;
|
|
errorMessage = (String) exclusion.get("error_message");
|
|
Map<String, List<String>> valueCounts = new LinkedHashMap<>();
|
|
for (String field : fields) {
|
|
Object v = fieldValues.get(field.trim());
|
|
if (v != null) {
|
|
valueCounts.computeIfAbsent(v.toString(), k -> new ArrayList<>()).add(field.trim());
|
|
}
|
|
}
|
|
for (List<String> fl : valueCounts.values()) {
|
|
if (fl.size() > 1) { conflictingFields = fl; break; }
|
|
}
|
|
}
|
|
}
|
|
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
|
result.put("is_valid", isValid);
|
|
result.put("error_message", isValid ? null : errorMessage);
|
|
result.put("conflicting_fields", conflictingFields);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 배제 옵션 조회: source_table에서 이미 선택된 값을 제외한 목록 반환
|
|
*/
|
|
public List<Map<String, Object>> getExcludedOptions(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
String companyCode = (String) params.get("company_code");
|
|
|
|
Map<String, Object> exclusion = sqlSession.selectOne(NS + "getCascadingMutualExclusionByCode", params);
|
|
if (exclusion == null) throw new NoSuchElementException("상호 배제 규칙을 찾을 수 없습니다.");
|
|
|
|
String sourceTable = (String) exclusion.get("source_table");
|
|
String valueColumn = (String) exclusion.get("value_column");
|
|
String labelColumn = (String) exclusion.get("label_column");
|
|
if (labelColumn == null || labelColumn.isEmpty()) labelColumn = valueColumn;
|
|
|
|
boolean hasCompanyCode = hasColumn(sourceTable, "company_code");
|
|
|
|
List<Object> queryParams = new ArrayList<>();
|
|
StringBuilder sql = new StringBuilder();
|
|
sql.append("SELECT ")
|
|
.append(valueColumn).append(" AS value, ")
|
|
.append(labelColumn).append(" AS label")
|
|
.append(" FROM ").append(sourceTable)
|
|
.append(" WHERE 1=1");
|
|
|
|
if (hasCompanyCode && !"*".equals(companyCode)) {
|
|
sql.append(" AND company_code = ?");
|
|
queryParams.add(companyCode);
|
|
}
|
|
|
|
Object selectedValuesParam = params.get("selected_values");
|
|
if (selectedValuesParam != null) {
|
|
List<String> excludeValues = new ArrayList<>();
|
|
for (String v : selectedValuesParam.toString().split(",")) {
|
|
String trimmed = v.trim();
|
|
if (!trimmed.isEmpty()) excludeValues.add(trimmed);
|
|
}
|
|
if (!excludeValues.isEmpty()) {
|
|
String placeholders = String.join(", ", Collections.nCopies(excludeValues.size(), "?"));
|
|
sql.append(" AND ").append(valueColumn).append(" NOT IN (").append(placeholders).append(")");
|
|
queryParams.addAll(excludeValues);
|
|
}
|
|
}
|
|
|
|
sql.append(" ORDER BY ").append(labelColumn);
|
|
|
|
return jdbcTemplate.queryForList(sql.toString(), queryParams.toArray());
|
|
}
|
|
|
|
private boolean hasColumn(String tableName, String columnName) {
|
|
String sql = "SELECT COUNT(*) FROM information_schema.columns WHERE table_name = ? AND column_name = ?";
|
|
Integer count = jdbcTemplate.queryForObject(sql, Integer.class, tableName, columnName);
|
|
return count != null && count > 0;
|
|
}
|
|
}
|