main
MonHun 2024-07-14 12:36:14 +09:00
parent 8fc70e4499
commit 0ed61a327b
11 changed files with 427 additions and 104 deletions

View File

@ -4,6 +4,7 @@ import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@ -26,9 +27,8 @@ public class AnalysisStandStatus {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private CustomThread cThread_Analyze_VideoMeta;
private CustomThread cThread_Analyze_StandSttus;
private CustomThread cThread_Maping_CctvIDStandNo;
private List<CustomThread> customThreads;
private CustomThread chkThreadStatus;
private LinkedHashMap<String, RestServiceData> map_stand_sttus;
@ -58,10 +58,13 @@ public class AnalysisStandStatus {
map_stand_sttus = new LinkedHashMap<String, RestServiceData>();
try {
customThreads = new ArrayList<CustomThread>();
customThreads.add(new CustomThread("mapingCctvStand", this, CustomThread.NO_SLEEP, this::init_map_stand_sttus, null, false));
customThreads.add(new CustomThread("makeMapStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Ai_Video_Meta, null, false));
customThreads.add(new CustomThread("analysisStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Stand_Sttus, null, false));
cThread_Maping_CctvIDStandNo = new CustomThread("mapingCctvStand", this, CustomThread.NO_SLEEP, this::init_map_stand_sttus, null, false);
cThread_Analyze_VideoMeta = new CustomThread("makeMapStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Ai_Video_Meta, null, false);
cThread_Analyze_StandSttus = new CustomThread("analysisStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Stand_Sttus, null, false);
// 이중화 체크 및 업무스래드 체크
chkThreadStatus = new CustomThread("chkThreadStatus", this, 3000, this::chkThreadStatus, null, false);
} catch (Exception e) {
logger.error("Start Fail: "+ e.toString());
@ -71,15 +74,20 @@ public class AnalysisStandStatus {
public void start() {
try {
cThread_Maping_CctvIDStandNo.start(Thread.MAX_PRIORITY);
cThread_Analyze_VideoMeta.start(Thread.NORM_PRIORITY);
cThread_Analyze_StandSttus.start(Thread.MIN_PRIORITY);
for(CustomThread ct : customThreads ){
ct.start();
}
chkThreadStatus.start();
} catch (Exception e) {
logger.error("Start Fail: "+ e);
}
}
private void chkThreadStatus() throws InterruptedException{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void init_map_stand_sttus() throws InterruptedException{
@ -102,9 +110,9 @@ public class AnalysisStandStatus {
}
if(map_stand_sttus.size() != 0){
logger.info("Stand Sttus HashMap 생성.");
logger.info("주기장(CCTV) 리스트 조회.");
}else{
logger.info("Stand Sttus HashMap 생성 실패.");
logger.info("주기장(CCTV) 리스트 조회 실패.");
}
Thread.sleep(1000 * (60 * 10)); // 10분
@ -119,7 +127,7 @@ public class AnalysisStandStatus {
*/
private void analysis_Ai_Video_Meta() throws InterruptedException{
if(dto.getDb_CctvList().size() == 0 || qRecvVideo.size() == 0 || map_stand_sttus.size() == 0) {
if(qRecvVideo.size() == 0 || map_stand_sttus.size() == 0) {
Thread.sleep(3000);
return ;
@ -128,21 +136,12 @@ public class AnalysisStandStatus {
AiAnalyzeStandSttus aiStandSttus;
int queSize = qRecvVideo.size();
int imapCnt = 0;
for(int idx = 0; idx<queSize; idx++){
//AiVideoMetaData lcData = qRecvVideo.poll();
//AiVideoMetaData lcData = qRecvVideo.take();
imapCnt = 0;
for(int idx = 0; idx<queSize; idx++){
List<AiVideoMetaData> lcDataList = qRecvVideo.take();
for( AiVideoMetaData lcData : lcDataList ){
// if(lcData.getCc_id().equals("123")){
// String adsf = "adf";
// }
imapCnt++;
aiStandSttus = new AiAnalyzeStandSttus();
aiStandSttus.setArcft_stand(lcData.getArcrft_yn());
@ -155,10 +154,8 @@ public class AnalysisStandStatus {
}
logger.info("AI메타정보 주기장 매핑 :" + imapCnt + " 건");
logger.info("AI메타정보 주기장 매핑 :" + lcDataList.size() + " 건");
// 주기장 항공기 상태 초기화
//map_stand_sttus.get(lcData.getCc_id()).setAircraft_sttus_ty("0");
}
@ -186,9 +183,6 @@ public class AnalysisStandStatus {
// 서비스큐 데이터 적재
store_Service_Data();
Thread.sleep(300);
}
@ -212,9 +206,6 @@ public class AnalysisStandStatus {
sStandNo = _mfltarr.getItemString("STAND_NO");
// logger.info("fltarr : " + fltarr.toString());
//logger.info("ARR-Stand : " + sStandNo);
sCctv = findCctvID(sStandNo);
if(sCctv.equals("")){
@ -227,7 +218,6 @@ public class AnalysisStandStatus {
* - 1 :
* - 2 :
*/
if( !_mfltarr.getItemString("APP_IN_DT").equals("") || !_mfltarr.getItemString("ACTL_ARR_DT").equals("")){
sSttusCD = "1";
@ -242,7 +232,6 @@ public class AnalysisStandStatus {
map_stand_sttus.get(sCctv).setSchdul_id(_mfltarr.getItemString("SCHDUL_ID"));
map_stand_sttus.get(sCctv).setAc_reg_no(_mfltarr.getItemString("AC_REG_NO"));
// logger.info("ARR --- StandNo:"+sStandNo + "|" + "cctv:" +sCctv + "|" + "CallSign:"+fltarr.get("CLSGN") + " ["+fltarr.toString()+"]");
}
// if(idx > 0 ) logger.info("도착 주기장 :" + (idx +1) + "건 갱신" );
@ -257,7 +246,6 @@ public class AnalysisStandStatus {
String sCctv, sStandNo, sSttusCD;
int idx;
int iDepStandTm = 15;
List<DataLoadHashMap> list_Dep = dto.getDb_FltDep();
@ -267,35 +255,6 @@ public class AnalysisStandStatus {
DataLoadHashMap _mfltdep = list_Dep.get(idx);
/* [2]PDC
* - 15 .
* - .
* - PDC .
*/
/* [3]PDC
* - 15 .
* - .
* - PDC .
*/
/* [4]PUSH-BACK
* - 15 .
* - .
* - PDC .
* - (ACTL_CLR_WAIT_DT)
*/
/* [5]PUSH-BACK
* -
* - A-CDM 'TAX'
*/
/* [9]PUSH-BACK
* -
* - A-CDM 'TAX'
*/
sSttusCD = "0";
sStandNo = _mfltdep.getItemString("STAND_NO");
@ -307,24 +266,30 @@ public class AnalysisStandStatus {
continue;
}
// if(sCctv.equals("107")){
// String asdf = "asdfasdf";
// }
// String sRecvTime = _mfltdep.getItemString("EXP_STAND_OFF_DT");
// sRecvTime = sRecvTime.concat("00.000");
// dt = LocalDateTime.parse(sRecvTime, df_Pattern);
String sRecvTime = _mfltdep.getItemString("EXP_STAND_OFF_DT");
sRecvTime = sRecvTime.concat("00.000");
dt = LocalDateTime.parse(sRecvTime, df_Pattern);
Duration diff = Duration.between(LocalDateTime.now(), dt);
String aiSttus;
// Duration diff = Duration.between(LocalDateTime.now(), dt);
sSttusCD = "0";
aiSttus = map_stand_sttus.get(sCctv).getAiStandSttus().getArcft_stand();
// String aiSttus = map_stand_sttus.get(sCctv).getAiStandSttus().getArcft_stand();
// 예상 주기장 출발 시각 15분 이내, 실제 주기장 출발 시간이 없음.
// if( aiSttus.equals("Y")){ //AI 상황분석 검증 완료전까지 주석
/* [2]PDC
* - .
* - PDC .
*/
/* [3]PDC
* - .
* - PDC .
*/
/* [4]PUSH-BACK
* - .
* - (ACTL_CLR_WAIT_DT)
*/
if(_mfltdep.getItemString("ACTL_STAND_OFF_DT").equals("")){
if(_mfltdep.getItemString("PDC_ISUE_TM").equals("")){
@ -338,18 +303,39 @@ public class AnalysisStandStatus {
}
}
/* [5]PUSH-BACK
* -
* - A-CDM 'TAX'
*/
/* [9]PUSH-BACK
* -
* - A-CDM 'TAX' -> VCCS Tax .
*/
if( !_mfltdep.getItemString("ACTL_STAND_OFF_DT").equals("")){
sSttusCD = "5"; //[5]PUSH-BACK 진행
if(_mfltdep.getItemString("TAX_YN").equals("Y")){
sSttusCD = "6"; //[9]PUSH-BACK 종료
}
}else{
// AI 음성 메타 분석정보로 PUSH-BACK 종료 판단
String strFltNum = _mfltdep.getItemString("flt_number");
// AnalysisVccsAiMetaStatus anaVccs = new
// List<HashMap<String, String>>
}
// }else{
// sSttusCD = "0";
// }
}
map_stand_sttus.get(sCctv).setClsgn(_mfltdep.getItemString("CLSGN"));
map_stand_sttus.get(sCctv).setAircraft_sttus_ty(sSttusCD);

View File

@ -0,0 +1,176 @@
package kr.gmtc.gw.standstatus.component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import kr.gmtc.gw.comp.rest.vo.RestServiceData;
import kr.gmtc.gw.comp.thread.CustomThread;
import kr.gmtc.gw.standstatus.config.QueueManageBean;
import kr.gmtc.gw.standstatus.database.dto.DataLoadDTO;
import kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap;
import kr.gmtc.gw.standstatus.kafka.vo.AiVideoMetaData;
import kr.gmtc.gw.standstatus.kafka.vo.KafkaRequestVoiceVo;
import kr.gmtc.gw.standstatus.vo.AiAnalyzeStandSttus;
import kr.gmtc.gw.standstatus.vo.VoiceVO;
import kr.gmtc.gw.standstatus.vo.VoiceVO.VoiceKeyword;
public class AnalysisVccsAiMetaStatus{
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private List<CustomThread> customThreads;
private CustomThread chkThreadStatus;
DateTimeFormatter df_Pattern = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS");
LocalDateTime dt;
private DataLoadDTO dto;
private QueueManageBean queMB;
private LinkedBlockingQueue<ArrayList<VoiceVO>> qRecvVccs;
// private LinkedList<RestServiceData> serviceList;
private List<HashMap<String, String>> filterTaxi;
public AnalysisVccsAiMetaStatus(DataLoadDTO dataLoadDTO, QueueManageBean queMB){
this.dto = dataLoadDTO;
this.queMB = queMB;
initialize();
}
public void initialize() {
qRecvVccs = queMB.getQRecvVccs();
try {
customThreads = new ArrayList<CustomThread>();
customThreads.add(new CustomThread("storeRequestTaxi", this, CustomThread.NO_SLEEP, this::storeRequestTaxi, null, false));
// customThreads.add(new CustomThread("makeMapStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Ai_Video_Meta, null, false));
// customThreads.add(new CustomThread("analysisStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Stand_Sttus, null, false));
// 이중화 체크 및 업무스래드 체크
chkThreadStatus = new CustomThread("chkThreadStatus", this, 3000, this::chkThreadStatus, null, false);
} catch (Exception e) {
logger.error("Start Fail: "+ e.toString());
}
}
public void start() {
try {
for(CustomThread ct : customThreads ){
ct.start();
}
chkThreadStatus.start();
} catch (Exception e) {
logger.error("Start Fail: "+ e);
}
}
private void chkThreadStatus() throws InterruptedException{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void storeRequestTaxi() throws InterruptedException{
int queSize = qRecvVccs.size();
filterTaxi = new ArrayList<HashMap<String, String>>();
for(int idx = 0; idx<queSize; idx++){
List<VoiceVO> lcDataList = qRecvVccs.take();
for( VoiceVO voice : lcDataList ){
// List<VoiceVO> voiceList = lcData.getData();
String[] clsgnToken = ((String) voice.getCallsign()).split("\\ ");
String clsgn_num = clsgnToken[1];
// 기장(p)이 요청(request)한 내용확인
if(voice.getSpeaker().equals("p") && voice.getDoc_type().equals("request")){
List<VoiceKeyword> vKeywords = voice.getKeywords();
boolean bKeywordYn = false;
for(VoiceKeyword vk : vKeywords){
if(vk.getKeyword().equals("request taxi")){
bKeywordYn = true;
break;
}
}
if(!bKeywordYn){
for(VoiceKeyword vk : vKeywords){
if(vk.getKeyword().equals("request")){
bKeywordYn = true;
break;
}
}
if(bKeywordYn){
for(VoiceKeyword vk : vKeywords){
if(vk.getKeyword().equals("taxi")){
bKeywordYn = true;
break;
}
}
}
}
if(bKeywordYn){
HashMap<String, String> mapTaxi = new HashMap<>();
String sComDt = (String) voice.getEndtime();
sComDt = sComDt.replace("-", "");
sComDt = sComDt.replace(" ", "");
sComDt = sComDt.replace(":", "");
sComDt = sComDt.substring(0, 12);
mapTaxi.put("clsgn_num", clsgn_num);
mapTaxi.put("clsgn", (String) voice.getCallsign());
mapTaxi.put("com_dt", sComDt);
filterTaxi.add(mapTaxi);
}
}
}
logger.info("AI음성메타(VCCS)정보 분석 :" + lcDataList.size() + " 건");
}
}
public List<HashMap<String, String>> getFilterTaxi(){
return this.filterTaxi;
}
}

View File

@ -1,14 +1,14 @@
package kr.gmtc.gw.standstatus.config;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import kr.gmtc.gw.comp.rest.vo.RestServiceData;
import kr.gmtc.gw.standstatus.kafka.vo.AiVideoMetaData;
import kr.gmtc.gw.standstatus.kafka.vo.KafkaRequestVoiceVo;
import kr.gmtc.gw.standstatus.vo.AlarmMsgVO;
import kr.gmtc.gw.standstatus.vo.VoiceVO;
import lombok.Getter;
import lombok.Setter;
@ -17,6 +17,7 @@ import lombok.Setter;
public class QueueManageBean {
private LinkedBlockingQueue<ArrayList<AiVideoMetaData>> qRecvVideo;
private LinkedBlockingQueue<ArrayList<VoiceVO>> qRecvVccs;
private LinkedBlockingQueue<AlarmMsgVO> qAlamMsg;
//private Map<Integer, LinkedList<RestServiceData>> mapServiceLists;
private LinkedList<RestServiceData> serviceList;
@ -24,6 +25,7 @@ public class QueueManageBean {
public QueueManageBean(){
this.qRecvVideo = new LinkedBlockingQueue<ArrayList<AiVideoMetaData>>(100000);
this.qRecvVccs = new LinkedBlockingQueue<ArrayList<VoiceVO>>(100000);
this.qAlamMsg = new LinkedBlockingQueue<AlarmMsgVO>(100000);
this.serviceList = new LinkedList<RestServiceData>();
this.bThredRunnig = false;

View File

@ -21,6 +21,7 @@ import kr.gmtc.gw.comp.rest.ServiceQueManager;
import kr.gmtc.gw.comp.thread.CustomThread;
import kr.gmtc.gw.standstatus.component.AnalysisAlarmStatus;
import kr.gmtc.gw.standstatus.component.AnalysisStandStatus;
import kr.gmtc.gw.standstatus.component.AnalysisVccsAiMetaStatus;
import kr.gmtc.gw.standstatus.config.QueueManageBean;
import kr.gmtc.gw.standstatus.database.datasource1.CmSelectDao;
import kr.gmtc.gw.standstatus.database.datasource2.IcSelectDao;
@ -90,6 +91,7 @@ public class MainController implements ApplicationListener<ContextClosedEvent> {
private DataLoadService dataLoadService;
private AnalysisStandStatus analysisStatusService;
private AnalysisAlarmStatus analysisAlarmStatus;
private AnalysisVccsAiMetaStatus vccsAiMeta;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -116,6 +118,7 @@ public class MainController implements ApplicationListener<ContextClosedEvent> {
analysisAlarmStatus = new AnalysisAlarmStatus(dataLoadDTO, queMB, dataLoadService);
vccsAiMeta = new AnalysisVccsAiMetaStatus(dataLoadDTO, queMB);
} catch (Exception e) {
logger.error("Start Fail: "+ e.toString());
@ -133,11 +136,12 @@ public class MainController implements ApplicationListener<ContextClosedEvent> {
// serviceQueManager.join();
// Thread.sleep(2000);
analysisStatusService.start();
// analysisStatusService.start();
// Thread.sleep(2000);
analysisAlarmStatus.start();
// // Thread.sleep(2000);
// analysisAlarmStatus.start();
vccsAiMeta.start();
} catch (Exception e) {

View File

@ -0,0 +1,70 @@
package kr.gmtc.gw.standstatus.kafka.consummer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.gmt.so.state.StateManager;
import kr.gmtc.gw.standstatus.config.QueueManageBean;
import kr.gmtc.gw.standstatus.kafka.vo.AiVideoMetaData;
import kr.gmtc.gw.standstatus.kafka.vo.KafkaRequestVo;
import kr.gmtc.gw.standstatus.kafka.vo.KafkaRequestVoiceVo;
import kr.gmtc.gw.standstatus.vo.VoiceVO;
@Service
public class KafkaMsgVccsListener {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final ObjectMapper objMapper = new ObjectMapper();
// @Resource(name = "recvVideoQ")
// LinkedBlockingQueue<AiVideoMetaData> recvVideoQ;
@Resource(name = "queueManageBean")
private QueueManageBean queMB;
@Autowired
private StateManager stateMgr;
@KafkaListener(topics = "${kafka.message.topic.recv.vccs}", groupId = "${kafka.consumer.group-id}")
public void listenAiAnalyzeVideo(@Payload String message) throws Exception{
if(stateMgr.isActive()){
KafkaRequestVoiceVo vo = null;
try {
if (message != null) {
vo = objMapper.readValue(message, KafkaRequestVoiceVo.class);
//recvVideoQ.add(vo.getData());
queMB.getQRecvVccs().offer((ArrayList<VoiceVO>) vo.getData());
}
} catch(Exception e) {
logger.error(e.getMessage());
}
logger.info("AI음성메타정보(VCCS) 수신 1건" );
}
}
public String getTime() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss"));
}
}

View File

@ -22,7 +22,7 @@ import kr.gmtc.gw.standstatus.kafka.vo.AiVideoMetaData;
import kr.gmtc.gw.standstatus.kafka.vo.KafkaRequestVo;
@Service
public class KafkaMessageListener {
public class KafkaMsgVideoListener {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final ObjectMapper objMapper = new ObjectMapper();
@ -37,7 +37,7 @@ public class KafkaMessageListener {
@Autowired
private StateManager stateMgr;
@KafkaListener(topics = "${kafka.message.topic.recv.video}", groupId = "${kafka.consumer.group-id}")
//@KafkaListener(topics = "${kafka.message.topic.recv.video}", groupId = "${kafka.consumer.group-id}")
public void listenAiAnalyzeVideo(@Payload String message) throws Exception{
if(stateMgr.isActive()){

View File

@ -27,7 +27,7 @@ import kr.gmtc.gw.standstatus.kafka.vo.KafkaServiceData;
import kr.gmtc.gw.standstatus.kafka.vo.KafkaServiceVO;
import kr.gmtc.gw.standstatus.kafka.vo.ResponsHeader;
@Component
//@Component
public class KafkaProduceStandSttus {
protected Logger logger;

View File

@ -0,0 +1,30 @@
package kr.gmtc.gw.standstatus.kafka.vo;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import kr.gmtc.gw.standstatus.vo.VoiceVO;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
@JsonPropertyOrder({ "result_code", "result_msg" })
public class KafkaRequestVoiceVo {
@JsonProperty("header")
private ResponsHeader header;
@JsonProperty("data")
private List<VoiceVO> data;
public KafkaRequestVoiceVo(){
this.data = new ArrayList<VoiceVO>();
}
}

View File

@ -0,0 +1,52 @@
package kr.gmtc.gw.standstatus.vo;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class VoiceVO {
@Getter
@Setter
public static class VoiceKeyword{
private String keyword;
private String tag;
}
@Getter
@Setter
public static class VoiceReadback{
private String result;
private String read_starttime;
private String read_endtime;
private List<VoiceKeyword> keywords;
}
private String starttime;
private String endtime;
private String com_type;
private String channel;
private String speaker;
private String facility;
private String callsign;
private String doc_type;
private String control_type;
private List<VoiceKeyword> keywords;
private List<VoiceReadback> readback;
private String frequency;
private String media_name;
private String text;
}

View File

@ -45,6 +45,7 @@ kafka:
topic:
recv:
video: ai.analyze.video
vccs: ai.analyze.voice_test
send:
sttus: ic.analyze.stand.status_test
alarm: ic.analyze.alarm_test

View File

@ -5,9 +5,11 @@
<select id="select_flt_dep" resultType="kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap">
<![CDATA[
select a.*, (select uic.FUN_GET_ACDM_STTUS_YN('D', a.dep_no, 'TAX') from dual) as tax_yn
from uic.V_FLT_DEP a
where a.exp_stand_off_dt between to_char(sysdate -1,'yyyymmdd')||'1500' and to_char(sysdate,'yyyymmdd')||'1459'
select b.flt_number, a.*, (select uic.FUN_GET_ACDM_STTUS_YN('D', a.dep_no, 'TAX') from dual) as tax_yn
from uic.V_FLT_DEP a, uic.SACP_FLT_SCHDUL b
where a.dep_no = b.schdul_no
and b.flt_se = 'D'
and a.exp_stand_off_dt between to_char(sysdate -1,'yyyymmdd')||'1500' and to_char(sysdate,'yyyymmdd')||'1459'
and a.stand_no in ( select stand_no from ucm.SACP_CCTVID_MAPPING where cctv_ty = '3' )
and a.flt_sttus <> 'END'
and (select uic.FUN_GET_ACDM_STTUS_YN('D', a.dep_no, 'BOR') from dual) = 'Y'