<div class="cont-box-inner search-box">
<div class="cont-box-inner">
<div class="title flex">
<h3>국내출장신청</h3>
<h3 class="red-txt">(①~③ 필수입력)</h3>
<div class="right-part">
<a2m-aplf-button
[rqstNo]="saveParam.bztrpRqstNo"
[statusCode]="saveParam.misApprvStatCd"
(save)="btnSave($event)"
(delete)="btnDelete()"
(init)="getForm0101()">
</a2m-aplf-button>
</div>
</div>
<div class="tbl grid-layout grid4">
<div class="grid-item">
<label>신청번호</label>
<div class="tbl-basic-td center">
{{saveParam?.bztrpRqstNo}}
</div>
</div>
<div class class="grid-item">
<label>소속부서</label>
<div class="tbl-basic-td center">
{{saveParam.rqstrDeptNm}}
</div>
</div>
<div class class="grid-item">
<label>신청일자</label>
<div class="tbl-basic-td center">
{{saveParam?.rqstDt | comDatePipe}}
</div>
</div>
<div class class="grid-item">
<label>신청자</label>
<div class="tbl-basic-td center">
{{saveParam.rqstrEmpNm}}
</div>
</div>
<div class class="grid-item colspan2">
<label>제목</label>
<div class="tbl-basic-td">
{{saveParam.apprvTitl}}
</div>
</div>
<div class class="grid-item">
<label>회계금액</label>
<div class="tbl-basic-td center">
{{ saveParam.rqstAmt | comCommaPipe}}
</div>
</div>
<div class="grid-item">
<label class="right">결재상태</label>
<div class="tbl-basic-td center">
{{saveParam.misApprvStatNm}}
</div>
</div>
</div>
</div>
</div>
<div class="cont-box-inner">
<div class="title">
<h3>① 예산내역</h3>
</div>
<div class="tbl grid-layout grid3">
<div class="grid-item colspan2">
<label class="verticalM">예산과목<em class="org-txt asterisk">*</em></label>
<div class="tbl-basic-td">
<div class="input-wrap w80">
<app-search-data
[component]="bdgPrjDtlDComponent"
[width]="bdgPrjDtlDWidth"
[height]="bdgPrjDtlDHeight"
[class]="['w40','w15']"
[disabled]="[!bscInptItemEnabled, !bscInptItemEnabled]"
[initValue]="[saveParam.bdgNm, saveParam.bdgCd]"
[param]="{bizClDivCd:'01'}"
(dataEmit)="dialogSaveParamChange($event, 'bdgCd')">
</app-search-data>
</div>
</div>
</div>
<div class class="grid-item">
<label class="verticalM">비용항목</label>
<div class="tbl-basic-td">
<div class="input-wrap">
<div class="input-wrap inputwnormal">
<ejs-textbox
class="e-input e-small"
[value]="saveParam.eptmNm"
[enabled]="false">
</ejs-textbox>
</div>
<div class="input-wrap inputwXshort">
<ejs-textbox
class="e-input e-small"
[value]="saveParam.eptmCd"
[enabled]="false">
</ejs-textbox>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cont-box-inner">
<div class="title">
<h3>② 출장정보</h3>
</div>
<div class="tbl grid-layout grid3">
<div class class="grid-item">
<label class="verticalM">출장기간<em class="org-txt asterisk">*</em></label>
<div class="tbl-basic-td">
<div class="flex datepicker-wrap">
<div class="datepicker-item px110">
<app-datepicker
[value]="saveParam.bztrpBginDt"
(dateEmit)="dateSaveParamChange($event, 'bztrpBginDt')"
[enabled]="bscInptItemEnabled"
selectionMode="date" #beginDatepicker [endDatepicker]="endDatepicker"
>
</app-datepicker>
</div>
<span class="cal-dash"></span>
<div class="datepicker-item px110">
<app-datepicker
[value]="saveParam.bztrpEndDt"
(dateEmit)="dateSaveParamChange($event, 'bztrpEndDt')"
[enabled]="bscInptItemEnabled"
selectionMode="date" #endDatepicker [beginDatepicker]="beginDatepicker"
>
</app-datepicker>
</div>
</div>
</div>
</div>
<div class class="grid-item">
<label class="verticalM">출장일수</label>
<div class="tbl-basic-td">
<div class="w100">
<div class="input-wrap px30">
<ejs-numerictextbox
class="e-input e-small right"
format="N"
min="0"
[showSpinButton]='false'
[(ngModel)]="saveParam.bztrpTotLodgNum"
[enabled]="bscInptItemEnabled"
(blur)="bztrpTotLodgNumChange($event)"
>
</ejs-numerictextbox>
</div>
박
<div class="input-wrap px40 center">
{{ saveParam.bztrpTotDdNum }}
</div>
일
</div>
</div>
</div>
<div class class="grid-item">
<label class="verticalM">출장형태<em class="org-txt asterisk">*</em></label>
<div class="tbl-basic-td">
<div class="select-wrap">
<ejs-dropdownlist
[dataSource]='sBztrpShpCd'
[fields]="{ text: 'nm', value: 'cd' }"
[value]="saveParam.bztrpShpCd"
(change)="dropdownSaveParamChange($event, 'bztrpShpCd')"
[enabled]="!saveParam.extrlLctrRqstNo">
</ejs-dropdownlist>
</div>
</div>
</div>
<div class class="grid-item">
<label>대결지정</label>
<div class="tbl-basic-td">
<div class="input-wrap px100">
<ejs-dropdownlist
[dataSource]='sUseYn'
[fields]="{ text: 'nm', value: 'cd' }"
[value]="grdD0101Data.sapvApntYn"
(change)="grdD0101Change($event, 'sapvApntYn')"
[enabled]="grdItemEnabled">
</ejs-dropdownlist>
</div>
</div>
</div>
<div class class="grid-item colspan2">
<label>업무 대행자</label>
<div class="tbl-basic-td">
<div class="input-wrap">
<app-search-data-grid
[component]="empDComponent"
[width]="empDWidth"
[height]="empDHeight"
[class]="['w60', '']"
[dataHidden]="true"
[enabled]="[grdItemEnabled, grdItemEnabled]"
[param]="{deptCd: grdD0101Data.bztrpDeptCd, deptNm: grdD0101Data.bztrpDeptNm }"
[initValue]="[grdD0101Data.angtEmpNm, grdD0101Data.angtEmpNo]"
(dataEmit)="grdD0101AngtNmChange($event)">
</app-search-data-grid>
</div>
</div>
</div>
<div class class="grid-item">
<label>교통수단</label>
<div class="tbl-basic-td">
<div class="input-wrap w100 flex">
<div class="input-wrap px100">
<ejs-dropdownlist
[dataSource]='sTrfcMensCd'
[fields]="{ text: 'nm', value: 'cd' }"
[value]="saveParam.trfcMensCd"
(change)="trfcMensCdChange($event.value)"
>
</ejs-dropdownlist>
</div>
<div *ngIf="saveParam.trfcMensCd === '7' && saveParam.bztrpRqstNo" class="input-wrap">
<button class="btn xx-small" (click)="fn_veclRqst()">배차신청</button>
</div>
</div>
</div>
</div>
<div class class="grid-item">
<label>식비</label>
<div class="tbl-basic-td">
<div class="input-wrap w100">
방문기관 식사 제공
<div class="input-wrap px30">
<ejs-numerictextbox
class="e-input e-small right"
format="N"
min="0"
[(ngModel)]="saveParam.vsitInstMealInclNum"
(blur)="ddctNumChange($event.value, 'vsitInstMealInclNum')"
[showSpinButton]="false"
[enabled]="bscInptItemEnabled">
</ejs-numerictextbox>
</div>
회
</div>
</div>
</div>
<div class="grid-item overlap">
<label class="label-float verticalM">숙박비</label>
<div class="tbl-basic-td">
<div class="tbl grid-layout grid1">
<div class="grid-item pd">
<div class="tbl-basic-td">
방문기관 제공
<div class="input-wrap px30">
<ejs-numerictextbox
class="e-input e-small right"
format="N"
min="0"
[(ngModel)]="saveParam.vsitInstLodgInclNum"
(blur)="ddctNumChange($event.value, 'vsitInstLodgInclNum')"
[showSpinButton]="false"
[enabled]="bscInptItemEnabled">
</ejs-numerictextbox>
</div>
회
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cont-box-inner">
<div class="title">
<h3>③ 출장지역(다중경로 선택가능)</h3>
<div class="right-part">
<div class="btn-wrap">
<button *ngIf="saveParam.misApprvStatCd == '01'"
type="button" class="btn small default disbtn" (click)="btnGrdD0102AddRow()" [disabled]="btnSaveDisabled">
<i class="material-icons iconL">add</i>행추가
</button>
<button *ngIf="saveParam.misApprvStatCd == '01'"
type="button" class="btn small default disbtn" (click)="btnGrdD0102RemoveRow()" [disabled]="btnSaveDisabled">
<i class="material-icons iconL">remove</i>행삭제
</button>
<button type="button" class="btn default iconbtn small" (click)="btnGrdD0102Excel()">
<i class="excel-icon"></i>엑셀
</button>
</div>
</div>
</div>
<ejs-grid #grdD0102
locale="ko"
[dataSource]="grdD0102Data"
[height]="grdD0102Height"
[allowExcelExport]="true"
(excelQueryCellInfo)="excelQueryCellInfoHandler($event)"
[allowResizing]="true"
(keydown)="keydown($event)"
[pageSettings]="pageSettings"
(recordDoubleClick)="recordDoubleClickGrdD0102($event)"
(created)="createdD0102()"
>
<e-columns>
<e-column field="idx" headerText="순번" width="60" minWidth="50" maxWidth="70" textAlign="Center" isPrimaryKey="true"></e-column>
<e-column field="chk" headerTextAlign="Center" width="40" minWidth="30" maxWidth="50" textAlign="Center" [headerTemplate]="template03_CHK_HEADER" [template]="template03_CHK">
<ng-template #template03_CHK_HEADER let-data>
<ejs-checkbox [(checked)]="headerChkGrdD0102" (change)="grdD0102HeaderChkChange($event)"></ejs-checkbox>
</ng-template>
<ng-template #template03_CHK let-data>
<ejs-checkbox [checked]="grdD0102Data[data.index]?.chk" (change)="grdD0102ChkChange($event, data.index)"></ejs-checkbox>
</ng-template>
</e-column>
<e-column field="crud" headerText="상태" width="60" minWidth="50" maxWidth="60" textAlign="Center" [template]="template03_CRUD" [visible]="false">
<ng-template #template03_CRUD let-data>
{{grdD0102Data[data.index]?.crud_view}}
</ng-template>
</e-column>
<e-column field="bstrGradCd" headerText="출장자직급코드" [visible]="false"></e-column>
<e-column field="trfcCd" headerText="교통코드" [visible]="false"></e-column>
<e-column
field="trfcDivCd"
[template]="template_TRFC_DIV_CD"
headerText="교통구분"
headerTextAlign="Center"
textAlign="Center"
width="100"
[visible]="false"
>
<ng-template #template_TRFC_DIV_CD let-data>
{{ grdD0102Data[data.index]?.trfcDivNm }}
</ng-template>
</e-column>
<e-column
field="mvBginDt"
[template]="template_mvBginDt"
headerText="시작일자<em class='g-asterisk'/>"
headerTextAlign="Center"
textAlign="Center"
[disableHtmlEncode]="false"
width="110">
<ng-template #template_mvBginDt let-data>
<app-datepicker-grid
[value]="grdD0102Data[data.index]?.mvBginDt"
(dateEmit)="grdD0102Change($event, data.index, 'mvBginDt')"
[enabled]="grdItemEnabled">
</app-datepicker-grid>
</ng-template>
</e-column>
<e-column
field="mvEndDt"
[template]="template_mvEndDt"
headerText="종료일자<em class='g-asterisk'/>"
headerTextAlign="Center"
[disableHtmlEncode]="false"
textAlign="Center"
width="110">
<ng-template #template_mvEndDt let-data>
<app-datepicker-grid
[value]="grdD0102Data[data.index]?.mvEndDt"
(dateEmit)="grdD0102Change($event, data.index, 'mvEndDt')"
[enabled]="grdItemEnabled">
</app-datepicker-grid>
</ng-template>
</e-column>
<e-column
field="stpnNm"
[template]="template_stpnNm"
headerText="출발지"
headerTextAlign="Center"
textAlign="Center"
width="140">
<ng-template #template_stpnNm let-data>
{{grdD0102Data[data.index]?.stpnNm}}
</ng-template>
</e-column>
<e-column
field="arpnNm"
[template]="template_arpnNm"
headerText="도착지"
headerTextAlign="Center"
textAlign="Center"
width="140">
<ng-template #template_arpnNm let-data>
{{grdD0102Data[data.index]?.arpnNm}}
</ng-template>
</e-column>
<e-column
field="chaeDivNm"
[template]="template_CHAE_DIV_CD"
headerText="요금구분"
headerTextAlign="Center"
textAlign="Center"
width="100">
<ng-template #template_CHAE_DIV_CD let-data>
{{ grdD0102Data[data.index]?.chaeDivNm }}
</ng-template>
</e-column>
<e-column
field="trfcAmt"
[template]="template03_trfcMensCd"
headerText="교통수단"
headerTextAlign="Center"
textAlign="Right"
width="100">
<ng-template #template03_trfcMensCd let-data>
<ejs-dropdownlist
[dataSource]='sTrfcMensCd'
[fields]="{ text: 'nm', value: 'cd' }"
[value]="grdD0102Data[data.index].trfcMensCd"
(change)="trfcMensCdChange($event.value, data.index)"
>
</ejs-dropdownlist>
<ng-template #template03_trfcMensCd_view>
{{ grdD0102Data[data.index]?.trfcMensCd | comCommaPipe }}
</ng-template>
</ng-template>
</e-column>
<e-column
field="trfcAmt"
[template]="template03_trfcAmt"
headerText="교통비"
headerTextAlign="Center"
textAlign="Right"
width="100">
<ng-template #template03_trfcAmt let-data>
<ejs-numerictextbox
*ngIf="grdD0102Data[data.index]?.crud_mode; else template03_trfcAmt_view"
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0102Data[data.index].trfcAmt"
(change)="grdD0102Change($event.value, data.index, 'trfcAmt')"
[enabled]="trfcCldvInptItemEnabled">
</ejs-numerictextbox>
<ng-template #template03_trfcAmt_view>
{{ grdD0102Data[data.index]?.trfcAmt | comCommaPipe }}
</ng-template>
</ng-template>
</e-column>
<e-column
field="drmtLodgYn"
[template]="template03_drmtLodgYn"
headerText="기숙사숙박여부"
headerTextAlign="Center"
textAlign="Center"
width="120">
<ng-template #template03_drmtLodgYn let-data>
<ejs-checkbox [checked]="grdD0102Data[data.index]?.drmtLodgYn == 'Y' ? true : false" (change)="grdD0102Change($event, data.index, 'drmtLodgYn')"
[disabled]="this.saveParam.misApprvStatCd !== '01'"
></ejs-checkbox>
</ng-template>
</e-column>
<e-column
field="lodgDdNum"
[template]="template02_lodgDdNum"
headerText="숙박일수"
headerTextAlign="Center"
textAlign="Center"
width="80">
<ng-template #template02_lodgDdNum let-data>
<div class="input-wrap w30">
<ejs-numerictextbox
*ngIf="grdD0102Data[data.index]?.crud_mode; else template02_lodgDdNum_view"
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0102Data[data.index].lodgDdNum"
(change)="grdD0102Change($event.value, data.index, 'lodgDdNum')"
[enabled]="trfcCldvInptItemEnabled">
</ejs-numerictextbox>
</div>
<ng-template #template02_lodgDdNum_view>
{{ grdD0102Data[data.index]?.lodgDdNum | comCommaPipe }}
</ng-template>
회
</ng-template>
</e-column>
<e-column
field="rmchrAmt"
[template]="template03_rmchrAmt"
headerText="숙박비"
headerTextAlign="Center"
textAlign="Right"
width="80"
>
<ng-template #template03_rmchrAmt let-data>
<ejs-numerictextbox
*ngIf="grdD0102Data[data.index]?.crud_mode; else template03_rmchrAmt_view"
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0102Data[data.index].rmchrAmt"
(change)="grdD0102Change($event.value, data.index, 'rmchrAmt')"
[enabled]="false">
</ejs-numerictextbox>
<ng-template #template03_rmchrAmt_view>
{{ grdD0102Data[data.index]?.rmchrAmt | comCommaPipe }}
</ng-template>
</ng-template>
</e-column>
<e-column
field="dwntBztrp"
[template]="template02_dwntTime"
headerText="시내출장"
headerTextAlign="Center"
textAlign="Center"
width="150"
*ngIf="dwntBztrpVisible"
>
<ng-template #template02_dwntTime let-data>
<div class="input-wrap flex" *ngIf="grdD0102Data[data.index]?.crud_mode else template02_dwntTime_view">
<div class="input-wrap w45">
<app-timepicker
[value]="grdD0102Data[data.index]?.dwntBztrpBginHh"
(dateEmit)="grdD0102Change($event, data.index, 'dwntBztrpBginHh')"
>
</app-timepicker>
</div>
<span>
~
</span>
<div class="input-wrap w45">
<app-timepicker
[value]="grdD0102Data[data.index]?.dwntBztrpEndHh"
(dateEmit)="grdD0102Change($event, data.index, 'dwntBztrpEndHh')"
>
</app-timepicker>
</div>
</div>
<ng-template #template02_dwntTime_view>
{{grdD0102Data[data.index]?.dwntBztrpBginHh | comDateTimePipe}} ~ {{grdD0102Data[data.index]?.dwntBztrpEndHh | comDateTimePipe}}
</ng-template>
</ng-template>
</e-column>
<e-column
field="extrlLctrYn"
[template]="template02_extrlLctrYn"
headerText="외부강의여부"
headerTextAlign="Center"
textAlign="Center"
width="130"
*ngIf="saveParam.bztrpShpCd == '5'"
>
<ng-template #template02_extrlLctrYn let-data>
<div class="input-wrap center w100">
<ejs-checkbox [checked]="grdD0102Data[data.index]?.extrlLctrYn == 'Y'" (change)="grdD0102Change($event, data.index, 'extrlLctrYn')"
[disabled]="this.saveParam.misApprvStatCd !== '01' || grdD0102Data[data.index]?.extrlLctrRqstNo"></ejs-checkbox>
<ng-container *ngIf="grdD0102Data[data.index]?.extrlLctrYn == 'Y' && saveParam.bztrpRqstNo && grdD0102Data[data.index]?.sn">
<ng-container *ngIf="grdD0102Data[data.index]?.extrlLctrRqstNo">
<button class="btn xx-small" (click)="fnEduPopup($event, data.index);">교육/자문신청 조회</button>
</ng-container>
<ng-container *ngIf="!grdD0102Data[data.index]?.extrlLctrRqstNo">
<button class="btn xx-small" (click)="fnEduPopup($event, data.index);">교육/자문신청 등록</button>
</ng-container>
</ng-container>
</div>
</ng-template>
</e-column>
<e-column
field="bstaNm"
[template]="template02_bstaNm"
headerText="목적지(기관)<em class='g-asterisk'/>"
headerTextAlign="Center"
[disableHtmlEncode]="false"
textAlign="Left"
width="100">
<ng-template #template02_bstaNm let-data>
<ejs-textbox
class="e-input e-small"
[value]="grdD0102Data[data.index]?.bstaNm"
(change)="grdD0102Change2($event, data.index, 'bstaNm')"
[enabled]="true">
</ejs-textbox>
</ng-template>
</e-column>
<e-column
field="bztrpCntn"
[template]="template02_bztrpCntn"
headerText="출장내역<em class='g-asterisk'/>"
headerTextAlign="Center"
[disableHtmlEncode]="false"
textAlign="Left"
width="150">
<ng-template #template02_bztrpCntn let-data>
<ejs-textbox
class="e-input e-small"
[value]="grdD0102Data[data.index]?.bztrpCntn"
(change)="grdD0102Change2($event, data.index, 'bztrpCntn')"
[enabled]="true">
</ejs-textbox>
</ng-template>
</e-column>
<e-column
field="supptTrfcAmt"
headerText="지원교통금액"
headerTextAlign="Center"
textAlign="Right"
width="100"
[template]="template02_supptTrfcAmt"
*ngIf="saveParam.bztrpShpCd == '5'"
>
<ng-template #template02_supptTrfcAmt let-data>
<ejs-numerictextbox
*ngIf="grdD0102Data[data.index]?.crud_mode; else template02_supptTrfcAmt_view"
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0102Data[data.index]?.supptTrfcAmt"
(change)="grdD0102Change($event.value, data.index, 'supptTrfcAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
<ng-template #template02_supptTrfcAmt_view>
{{ grdD0102Data[data.index]?.supptTrfcAmt | comCommaPipe }}
</ng-template>
</ng-template>
</e-column>
<e-column
field="supptCpdAmt"
headerText="지원일비금액"
headerTextAlign="Center"
textAlign="Right"
width="100"
[template]="template02_supptCpdAmt"
*ngIf="saveParam.bztrpShpCd == '5'"
>
<ng-template #template02_supptCpdAmt let-data>
<ejs-numerictextbox
*ngIf="grdD0102Data[data.index]?.crud_mode; else template02_supptCpdAmt_view"
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0102Data[data.index]?.supptCpdAmt"
(change)="grdD0102Change($event.value, data.index, 'supptCpdAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
<ng-template #template02_supptCpdAmt_view>
{{ grdD0102Data[data.index]?.supptCpdAmt | comCommaPipe }}
</ng-template>
</ng-template>
</e-column>
<e-column
field="supptFoodEpnsAmt"
headerText="지원식비금액"
headerTextAlign="Center"
textAlign="Right"
width="100"
[template]="template02_supptFoodEpnsAmt"
*ngIf="saveParam.bztrpShpCd == '5'"
>
<ng-template #template02_supptFoodEpnsAmt let-data>
<ejs-numerictextbox
*ngIf="grdD0102Data[data.index]?.crud_mode; else template02_supptFoodEpnsAmt_view"
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0102Data[data.index]?.supptFoodEpnsAmt"
(change)="grdD0102Change($event.value, data.index, 'supptFoodEpnsAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
<ng-template #template02_supptFoodEpnsAmt_view>
{{ grdD0102Data[data.index]?.supptFoodEpnsAmt | comCommaPipe }}
</ng-template>
</ng-template>
</e-column>
<e-column
field="rmrkCntn"
[template]="template02_rmrkCntn"
headerText="비고"
headerTextAlign="Center"
textAlign="Left"
width="300">
<ng-template #template02_rmrkCntn let-data>
<ejs-textbox
class="e-input e-small"
[value]="grdD0102Data[data.index]?.rmrkCntn"
(change)="grdD0102Change($event.value, data.index, 'rmrkCntn')"
[enabled]="true">
</ejs-textbox>
</ng-template>
</e-column>
</e-columns>
</ejs-grid>
</div>
<div class="cont-box-inner">
<div class="title">
<h3>④ 여비산출내역(출장자내역)</h3>
<div class="left-part" style="padding-top: 5px">
<p class="red-txt"> * 총 출장비 : {{saveParam.rqstAmt | comCommaPipe }}</p>
</div>
</div>
<div class="tbl-wrap">
<table class="tbl">
<caption></caption>
<colgroup>
<col style="width: 10%">
<col style="width: 10%">
<col style="width: 10%">
<col style="width: 10%">
<col style="width: 10%">
<col style="width: 10%">
<col style="width: 12%" *ngIf="saveParam.bztrpShpCd == '5'">
<col style="width: 10%">
<col style="width: 12%" *ngIf="saveParam.bztrpShpCd == '5'">
<col style="width: 10%">
<col style="width: 20%">
<col style="width: 12%" *ngIf="saveParam.bztrpShpCd == '5'">
<col style="width: 10%">
</colgroup>
<thead>
<tr>
<th scope="col">출장자</th>
<th scope="col">직원번호</th>
<th scope="col">직급</th>
<th scope="col">예금주</th>
<th scope="col">0원 출장여부</th>
<th scope="col">교통비</th>
<th scope="col" *ngIf="saveParam.bztrpShpCd == '5'">제외교통비금액</th>
<th scope="col">일비</th>
<th scope="col" *ngIf="saveParam.bztrpShpCd == '5'">제외일비금액</th>
<th scope="col">숙박비</th>
<th scope="col">식비</th>
<th scope="col" *ngIf="saveParam.bztrpShpCd == '5'">제외식비금액</th>
<th scope="col">총합계</th>
</tr>
</thead>
<tbody>
<tr>
<td>
{{grdD0101Data.bztrpEmpNm}}
</td>
<td>
{{grdD0101Data.bztrpEmpNo}}
</td>
<td>
{{grdD0101Data.bztrpGradNm}}
</td>
<td>
{{grdD0101Data.dpownNm}}
</td>
<td>
<app-checkbox
[value]="saveParam.bztrp0AmtYn"
(dataEmit)="bztrp0AmtYnChange($event)"
[disabled]="!bscInptItemEnabled">
</app-checkbox>
</td>
<td>
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0101Data?.trfcAmt"
(change)="grdD0101Change($event.value, 'trfcAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
</td>
<td *ngIf="saveParam.bztrpShpCd == '5'">
<div class="input-wrap w80">
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0101Data?.xcldTrfcAmt"
(change)="grdD0101Change($event.value, 'xcldTrfcAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
</div>
<div class="input-wrap">
<button class="btn xx-small" (click)="fn_dialog('xTrfc')">?</button>
</div>
</td>
<td>
<div class="input-wrap w80">
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0101Data?.atplTrfcAmt"
(change)="grdD0101Change($event.value, 'atplTrfcAmt')"
[enabled]="trfcCldvInptItemEnabled">
</ejs-numerictextbox>
</div>
<div class="input-wrap">
<button class="btn xx-small" (click)="fn_dialog('daily')">?</button>
</div>
</td>
<td *ngIf="saveParam.bztrpShpCd == '5'">
<div class="input-wrap w80">
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0101Data?.xcldCpdAmt"
(change)="grdD0101Change($event.value, 'xcldCpdAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
</div>
<div class="input-wrap">
<button class="btn xx-small" (click)="fn_dialog('xCpd')">?</button>
</div>
</td>
<td>
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0101Data?.lodgAmt"
(change)="grdD0101Change($event.value, 'lodgAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
</td>
<td>
<span class="input-wrap w100 flex">
<div class="input-wrap w30 flex">
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false"
[min]="0"
[value]="grdD0101Data?.mealCnt"
(change)="grdD0101Change($event.value, 'mealCnt')"
[enabled]="false"
>
</ejs-numerictextbox>
<div style="margin:0px">식</div>
</div>
<div class="input-wrap w70 flex" style="margin:0px;">
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false" min="0"
[value]="grdD0101Data?.mealAmt"
(change)="grdD0101Change($event.value, 'mealAmt')"
>
</ejs-numerictextbox>
<div style="margin:0px;">
<button class="btn xx-small" style="margin:0px;margin-right:2px" (click)="fn_calMeal('+')">+</button>
<button class="btn xx-small" style="margin:0px;margin-right:2px" (click)="fn_calMeal('-')">-</button>
</div>
<div style="margin:0px;">
<button class="btn xx-small" (click)="fn_dialog('meal')">?</button>
</div>
</div>
</span>
</td>
<td *ngIf="saveParam.bztrpShpCd == '5'">
<div class="input-wrap w80">
<ejs-numerictextbox
class="e-input e-small right"
format="N" [showSpinButton]="false"
[value]="grdD0101Data?.xcldChfdAmt"
(change)="grdD0101Change($event.value, 'xcldChfdAmt')"
[enabled]="false"
>
</ejs-numerictextbox>
</div>
<div class="input-wrap">
<button class="btn xx-small" (click)="fn_dialog('xChfd')">?</button>
</div>
</td>
<td class="right">{{ grdD0101Data?.totAmt | comCommaPipe }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<app-toast-util (toastEmit)="toastEmit($event)"></app-toast-util>
import { ChangeDetectorRef, Component, Input, OnInit, Renderer2, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subject, takeUntil } from 'rxjs';
import { CommonUtil } from 'src/app/shared/utils/common-util';
import { PerUtil } from 'src/app/util/per/per-util';
import { PerEmpDialogComponent } from '../../dialog/per/per-emp-dialog.component';
import { CommonGridService } from './../../../kernel/service/common.grid.service';
import { MatDialog } from '@angular/material/dialog';
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
import { GridComponent, PageSettingsModel } from '@syncfusion/ej2-angular-grids';
import { CommonApvService } from 'src/app/kernel/service/common.apv.service';
import { CommonDateService } from 'src/app/kernel/service/common.date.service';
import { CommonExcelService } from 'src/app/kernel/service/common.excel.service';
import { CommonHttpService } from 'src/app/kernel/service/common.http.service';
import { CommonMessageService } from 'src/app/kernel/service/common.message.service';
import { NeroComponent } from 'src/app/shared/component/nero/nero.component';
import { CommonMatDialogConfig } from 'src/app/shared/config/common-mat-dialog.config';
import { GridAddModel, GridDeleteModel, GridUpdateModel, GridViewModel } from 'src/app/shared/model/grid.model';
import { ComCommaPipe } from 'src/app/shared/pipe/com-comma.pipe';
import { ComDateTimePipe } from 'src/app/shared/pipe/com-date-time.pipe';
import { ComDatePipe } from 'src/app/shared/pipe/com-date.pipe';
import { ComHmsTimePipe } from 'src/app/shared/pipe/com-hms-time.pipe';
import { CommonDate } from 'src/app/shared/utils/common-date';
import { GafUtil } from 'src/app/util/gaf/gaf-util';
import message from 'src/assets/json/common.message.json';
import { BdgPrjEptmDialogComponent } from '../../dialog/bdg/bdg-prj-eptm-dialog.component';
import { GafAsetOutYnYComponent } from '../../dialog/gaf/gaf-aset-out-yn-y-dialog.component';
import { Gaf0708D01Data, Gaf0708D02Data, Gaf0708D03Data, Gaf0708Model } from './gaf0708.model';
import { Gaf070810Component } from './gaf070810.component';
import { Gaf070815Component } from './gaf070815.component';
import { Gaf0708dpComponent } from './gaf0708dp.component';
import { Gaf0708mComponent } from './gaf0708m.component';
import { Gaf0708m2Component } from './gaf0708m2.component';
/********************************************************************************
* @author ysb
* @since
* [시스템명] 경영정보
* [업 무 명] 근태
* [세부업무] 국내출장신청
* [설 명] 국내출장신청 팝업을 구성하는 Typescript.
********************************************************************************/
@Component({
selector: 'app-gaf0708',
templateUrl: './gaf070801.component.html',
styles: [
]
})
export class Gaf070801Component implements OnInit {
@Input()
pgmId = 'gaf0708';
/** 저장 validation */
saveValid = 'N';
/** 업무구분코드 */
busiDivCd = '';
/** 정산여부 */
fixYn = '';
/** 조회용 Param */
searchParam: any = new Object();
/** 저장용 Param */
saveParam: any = new Gaf0708Model();
/** 여비산출내역 저장용 Param */
grdD0101Data: any = new Object();
/** 여비산출내역 GridComponent */
// @ViewChild('grdD0101')
// grdD0101: GridComponent | undefined;
// grdD0101Height = 50;
/** 여비산출내역 Array datagrid1 ac */
// grdD0101Data: any | Object[] = [];
/** 여행명세 GridComponent */
@ViewChild('grdD0102')
grdD0102: GridComponent | undefined;
grdD0102Height = 100;
/** 여행명세 Array datagrid2 ac2 */
grdD0102Data: any [] = [];
copyGrdD0102: any [] = [];
copyLodgD0102: any [] = [];
/** 출장내용 GridComponent */
@ViewChild('grdD0103')
grdD0103: GridComponent | undefined;
grdD0103Height = 90;
/** 출장내용 Array datagrid3 ac3 */
// grdD0103Data: Array<Gaf0708D03Data> = new Array<Gaf0708D03Data>();
grdD0103Data: any | Object[] = [];
/** 전자결재 직위 코드 변수 */
gwpAdecPosiCd: any;
//사용자 정보
userInfo = CommonUtil.getLocalStorage('SESS_USER');
/** Grid 가상화 옵션 */
isVirtualization = false;
/** page 설정 */
pageSettings: PageSettingsModel | undefined;
/** 헤더 체크박스 제어 변수 */
headerChkGrdD0103 = false;
headerChkGrdD0101 = false;
headerChkGrdD0102 = false;
toastObj: any;
adminChk: boolean = false;
destroy: Subject<boolean> = new Subject<boolean>();
perEmpDComponent = PerEmpDialogComponent;
perEmpDWidth = PerUtil.perEmpDWidth;
perEmpDHeight = PerUtil.perEmpDHeight;
// 직원조회 다이얼로그
empDComponent: any = PerEmpDialogComponent;
empDWidth = PerUtil.perEmpDWidth; // 1200px
empDHeight = PerUtil.perEmpDHeight; // 500px
gafExtrDComponent = PerEmpDialogComponent;
gafExtrDWidth = PerUtil.perEmpDWidth; // 1200px
gafExtrDHeight =PerUtil.perEmpDHeight; // 500px
/** 예산과제검색 다이얼로그 */
bdgPrjDtlDComponent: any = BdgPrjEptmDialogComponent;
bdgPrjDtlDWidth =PerUtil.perEmpDWidth; // 1200px
bdgPrjDtlDHeight = PerUtil.perEmpDHeight; // 500px
/** 자산 검색 다이얼로그 */
astDComponent = PerEmpDialogComponent;
astDWidth = PerUtil.perEmpDWidth; // 1200px
astDHeight = PerUtil.perEmpDHeight; // 500px
/* 공통코드 */
/** 사업장코드 */
BPLC_CD_LIST: any[] = [];
/** 출장형태코드 */
BTRP_SHP_CD_LIST: any[] = [];
/** 교통구분코드 */
TRFC_DIV_CD_LIST: any[] = [];
/** 내부인여부 */
IMN_YN_LIST: any[] = [{'nm':'내부인','cd':'Y'},{'nm':'외부인','cd':'N'}];
/** 요금구분 */
CHAE_DIV_CD_LIST: any[] = [];
/** 대결지정여부 */
RPRV_APNT_YN_LIST: any[] =[];
//겸직겸무 부서콤보리스트
cncPosComboList: any[] = [];
// 화면 및 프로세스 제어 변수
/** 휴가 대결 지정 프로세스 사용 여부 */
rprvApntMngrAuthYn = 'Y';
/** 결재상신 버튼 제어 변수 */
btnRqstDisabled = false;
/** 저장 버튼 제어 변수 */
btnSaveDisabled = false;
/** 삭제 버튼 제어 변수 */
btnDeleteDisabled = true;
/** 담당자 취소 버튼 제어 변수 */
btnCancelDisabled = true;
/** 출장내용 grid 입력 제어 변수 itemEnableYn */
grdItemEnabled = true;
/** 기본 입력 항목 제어 변수 */
bscInptItemEnabled = true;
/** 기본 그리드 입력 항목 제어 변수 itemEnableDefault */
bscGrdInptItemEnabled = true;
/** 교통 구분별 입력 항목 제어 변수 itemRenderEnabledTRP_COLS */
trfcCldvInptItemEnabled = true;
/** 임원 숙박비 항목 제어 FLAG */
extvLoadFlag : boolean = false;
/** 외부강의여부 제어 변수 */
extrlLctrDisabled = false;
// asetDDisabled
//파일관련
@ViewChild("nero")
nero?: NeroComponent;
fileDivCd: string = 'gaf0708';
//파일공통
neroMode = NeroComponent.MODE_NEW;
neroIds: string[] = [];
post: any = new Object();
totDay: number = 0; // 출장일수(외부인&출장일수3일 이상일 경우 식비 직접 수정가능 처리때문에 추가) 2022.07.11
mealAmt: number = 0; // 식비(외부인&출장일수3일 이상일 경우 식비 직접 수정가능 처리때문에 추가) 2022.07.11
// mealPay: number = 10000; // 하루 식비
lodgAmt: number = 0; // 총 숙박비 (출장기간 변경시 dialog에 있던 값을 불러오기 위해)
//시내출장여부
dwntBztrpVisible : boolean = false;
tempTotAmt : number = 0;
supptAmt = 0; //출장지원비
private unlistener!: (() => void);
constructor(
private dialog: MatDialog,
private commonGridService: CommonGridService,
private commonDateService: CommonDateService,
private activatedRoute: ActivatedRoute,
private commonHttpService: CommonHttpService,
private commonMessageService: CommonMessageService,
private commonExcelService: CommonExcelService,
private renderer2: Renderer2,
private comHmsTimePipe: ComHmsTimePipe,
private comDatePipe: ComDatePipe,
private comDateTimePipe: ComDateTimePipe,
private comCommaPipe: ComCommaPipe,
private commonApvService: CommonApvService,
private cdr: ChangeDetectorRef,
) {
this.activatedRoute.queryParams
.pipe(takeUntil(this.destroy))
.subscribe((params) => {
//console.log(params);
if(CommonUtil.isNotEmpty(params)) {
const bztrpRqstNo = params["bztrpRqstNo"];
if (CommonUtil.isNotEmpty(bztrpRqstNo)) {
this.searchParam.bztrpRqstNo = bztrpRqstNo;
}
}
this.initPopup();
});
}
ngOnInit(): void {
this.pageSettings = { pageSize: 50 };
this.setAuth();
}
ngOnDestroy(): void {
this.destroy.next(true);
this.destroy.unsubscribe();
}
setAuth() {
this.adminChk = CommonUtil.hasRole('000000','R00201'); // 권한여부
}
/*----------------- Init Method Start -----------------*/
/**
* param의 bztrpRqstNo 변경등의 대응을 위한 팝업 초기화
*
*/
initPopup(): void {
// 출장현황조회에서 창을 호출했을 때
if (this.pgmId === 'gaf0708') {
this.changeBtnDisabled(); // 버튼 제어 불가능하게..
}
this.initCode();
}
/**
* 공통코드 초기 설정
* > 결재상태, 출장형태, 정산여부
*/
sWrkAreaCd : object = [];
sBztrpShpCd : object = [];
sPrtbYn : object = [];
sUseYn : object = [];
sInthVecl : object = [{cd:'N', nm:'일반'},{cd:'Y', nm:'공용(동승)'}]; // 원내차량여부
sTrfcMensCd : Object[] | any[] = []; // 교통수단
initCode(): void {
const param = [ { comnGrpCd : 'WRK_AREA_CD' } // 사업장
, { comnGrpCd : 'BZTRP_SHP_CD' } // 출장형태
, { comnGrpCd : 'PRTB_YN' } // 휴대여부
, { comnGrpCd : 'USE_YN' } // 대결지정 - 사용여부
, { comnGrpCd : 'CHAE_DIV_CD' } // 요금구분코드
, { comnGrpCd : 'TRFC_DIV_CD' } // 교통구분코드
, { comnGrpCd : 'TRFC_MENS_CD' } // 교통수단코드
];
this.commonHttpService.getCode(param).subscribe({
next: (response) => {
if(CommonUtil.isNotEmpty(response)) {
this.sWrkAreaCd = CommonUtil.addFirstCodeList('TEXT_ALL', response.WRK_AREA_CD);
this.sBztrpShpCd = CommonUtil.addFirstCodeList('TEXT_SELECT', response.BZTRP_SHP_CD);
this.sPrtbYn = CommonUtil.addFirstCodeList('TEXT_SELECT', response.PRTB_YN);
this.sUseYn = response.USE_YN;
this.sTrfcMensCd = response.TRFC_MENS_CD;
this.CHAE_DIV_CD_LIST = response.CHAE_DIV_CD;
this.TRFC_DIV_CD_LIST = response.TRFC_DIV_CD;
}
},
error: () => {},
complete: () => {
//겸직겸무 부서콤보리스트
// this.commonApvService.getCncposCombo(null, this.toastObj, (state:boolean, response:any) => {
// if(state) {
// this.cncPosComboList = response;
// }
// });
// 공통코드 조회 후 조회
if (CommonUtil.isNotEmpty(this.searchParam.bztrpRqstNo)) {
this.getForm0101(); //출장신청 조회 (마스터)
} else {
this.initSaveParam();
}
}
});
}
/**
* 검색조건 초기 설정
*/
initSaveParam(): void {
this.saveParam = new Gaf0708Model();
this.saveParam.rqstrEmpNo = this.userInfo.empNo; //신청자사원번호
this.saveParam.rqstrEmpNm = this.userInfo.name; //신청자사원이름
this.saveParam.rqstrDeptCd = this.userInfo.deptCd; //부서코드
this.saveParam.rqstrDeptNm = this.userInfo.deptNm; //부서명
//전자결재
this.saveParam.misApprvStatNm = '작성중'; // 결재상태
this.saveParam.misApprvStatCd = '01'; // 결재상태코드
this.saveParam.bplcCd = this.userInfo.wrkAreaCd; // 사업장코드설정
this.saveParam.rqstrGradNm = this.userInfo.gradNm; // 직급명설정(그룹웨어 결제문서에서 필요)
this.saveParam.rqstrGradCd = this.userInfo.gradCd; // 직급명설정(그룹웨어 결제문서에서 필요)
this.saveParam.rqstAmt = 0;
this.saveParam.trfcMensCd = this.sTrfcMensCd[1].cd; // 교통수단
//console.log(this.userInfo);
// let param = {imnYn:'Y', sapvApntYn:'N'}
this.grdD0101Data.imnYn = 'Y';
this.grdD0101Data.sapvApntYn = 'N';
// const obj: GridAddModel = {
// gridObj : this.grdD0101
// , gridData : this.grdD0101Data
// , position: 'bottom'
// , newData : param
// }
// this.commonGridService.gridAddRow(obj);
this.getBstrInfo();
// if(!this.adminChk) {
this.fn_trexInfo();
// }
}
/*----------------- Init Method End -----------------*/
/*----------------- Baclend Handler Start -----------------*/
// 신규 시 출장자 정보 조회
getBstrInfo() {
const param = { empNo : this.userInfo.empNo, hffcDivCd: '1' };
this.commonHttpService.get('/per/dialog/getemplist.do', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response: any) => {
const data = response.body?.[0];
this.grdD0101Data.bztrpEmpNo = data?.empNo ?? '';
this.grdD0101Data.bztrpEmpNm = data?.name ?? '';
this.grdD0101Data.bztrpDeptCd = data?.deptCd ?? '';
this.grdD0101Data.bztrpDeptNm = data?.deptNm ?? '';
this.grdD0101Data.bztrpGradCd = data?.gradCd ?? '';
this.grdD0101Data.bztrpGradNm = data?.gradNm ?? '';
this.grdD0101Data.bstrPosiCd = data?.posiCd ?? '';
this.grdD0101Data.bankCd = data?.bztrpBankCd ?? '';
this.grdD0101Data.bactNo = data?.bztrpBactNo ?? '';
this.grdD0101Data.dpownNm = data?.name ?? '';
this.grdD0101Data.scpsGrdCd = data?.scpsGrdCd ?? ''; //신분등급코드
this.grdD0101Data.trexGrdCd = data?.gradDivCd ?? ''; //여비등급
if(CommonUtil.isNotEmpty(data?.posiCd)) {
this.grdD0101Data.artckDivCd = data.posiCd === '10' ? '844-030' : '844-010';
}
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
if (
CommonUtil.isEmpty(this.grdD0101Data.bankCd) ||
CommonUtil.isEmpty(this.grdD0101Data.bactNo) ||
CommonUtil.isEmpty(this.grdD0101Data.dpownNm)
) {
this.commonMessageService.showMsg(this.toastObj, { message : '경비계좌가 등록되어있지 않습니다. 급여관리자에게 문의하시기 바랍니다.', type : 'W' });
}
}
});
}
/**
* 국내출장 마스터정보조회
* @see doSearchTrp()
*/
getForm0101(): void {
this.commonHttpService
.get('/gaf/gaf0708/getfrmr01.do', this.searchParam).pipe(takeUntil(this.destroy)).subscribe({
next: (response : any) => {
if (CommonUtil.isNotEmpty(response)) {
console.log(response.body);
this.saveParam = response.body;
const gridMvGrid: GridViewModel = {
gridData: response.body.mvList,
};
const gridCntnGrid: GridViewModel = {
gridData: response.body.cntnList,
};
this.grdD0101Data = response.body.btrpEmpVo[0]; //출장자
this.grdD0102Data = this.commonGridService.gridList(gridMvGrid); //경유지
this.grdD0103Data = this.commonGridService.gridList(gridCntnGrid); //출장내용
// 작성중일때 무조건 수정모드로
if(this.saveParam?.misApprvStatCd <= '01') {
this.grdD0101Data.crud_mode = true;
}
this.copyGrdD0102 = JSON.parse(JSON.stringify(this.grdD0102Data)); //경유지 그리드 복사
this.copyLodgD0102 = JSON.parse(JSON.stringify(this.grdD0102Data)); //경유지 숙박비 그리드 복사
if(CommonUtil.isNotEmpty(this.grdD0102Data) && CommonUtil.isEmpty(this.grdD0101Data.totAmt)) {
this.grdD0101Data.totAmt = this.tempTotAmt;
}
if(CommonUtil.isNotEmpty(this.grdD0102Data)) {
// 시내출장 컬럼 visible -> 첫번째 행이 시내출장이며 그 다음행도 시내출장임
this.grdD0102Data[0].stpnCd == this.grdD0102Data[0].arpnCd ? this.dwntBztrpVisible = true : this.dwntBztrpVisible = false;
// if('5' === this.saveParam.bztrpShpCd) {
// // 지원금액 합계
// this.grdD0102Data.forEach((item:any)=>{
// this.supptAmt += item.supptCpdAmt + item.supptFoodEpnsAmt + item.supptTrfcAmt;
// })
// }
// console.log("지원금 합계", this.supptAmt);
}
}
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
//this.resetFlag = false;
//this.commonGridService.customResortingGridData(this.grdR01Data, this.grdR01, this.destroy);
}
})
}
/**
* 저장
*
* @see doTrpRqstSave()
* @param misApprvStatCd '
*/
async saveForm0101(misApprvStatCd: string = '') {
let confirmMsg = '';
// TODO 검증하기
//const validation = this.checkBeforeSave();
//데이터 세팅
this.saveParam.bztrpEmpVo = this.grdD0101Data; //출장자
this.saveParam.mvList = this.grdD0102Data; //경유지
this.saveParam.cntnList = this.grdD0103Data; //출장내용
this.saveParam.approvYn = misApprvStatCd;
this.saveParam.dwntBztrpCd = this.dwntBztrpVisible ? '1' : '0'; // 시내출장여부 1:시내출장 0:전일출장
if (misApprvStatCd === '01') {
// 저장 처리일 때
confirmMsg = message.com_info_save; // 저장 하시겠습니까?
} else {
// 외부강의 일 때 -> 교육신청 등록 해야함
if(this.saveParam.bztrpShpCd == '5') {
const cnt = this.grdD0102Data.filter((d) => d.extrlLctrYn === 'Y').length;
if(cnt === 0) {
this.commonMessageService.showMsg(this.toastObj, { message: "출장지역에서 하나 이상의 외부강의여부에 체크 해주시기 바랍니다.", type: 'W'});
return;
}
}else {
if(this.grdD0102Data.filter((f) => f.dwntBztrpCd === '1').length > 1) { // 시내출장 행이 여러개
this.commonMessageService.showMsg(this.toastObj, { message: "시내출장은 한 건만 등록할 수 있습니다", type: 'W'});
return;
}
}
// 대결지정 사용일 때 대리인 필수
if(CommonUtil.isNotEmpty(this.grdD0101Data)) {
if(this.grdD0101Data.sapvApntYn === 'Y') {
if(CommonUtil.isEmpty(this.grdD0101Data.angtEmpNo)) {
this.commonMessageService.showMsg(this.toastObj, { message : message.com_warn_need_data.replace('{0}','대결지정 사용일 때 대리인'), type : 'W', title : '경고알람' });
return;
}
// const schema2 = {
// angtEmpNo: { title: '대리인', required: true },
// };
// const validation2 = this.commonGridService.gridValidation(this.grdD0101, this.grdD0101Data, this.toastObj, schema2);
// if(!validation2) { return; }
}
}
// 결재상신처리일 때
// 저장하지 않았으면 결재상신 할 수 없음
if(CommonUtil.isEmpty(this.saveParam.bztrpRqstNo)) {
this.commonMessageService.showMsg(this.toastObj, { message: '저장 후 전자결재 요청 바랍니다.', type: 'W'});
return;
}
// 외부강의 일 때 -> 교육신청 등록 해야함
if(this.saveParam.bztrpShpCd == '5') {
let validate = true;
const extrlList = this.grdD0102Data.filter((item:any) => CommonUtil.isEmpty(item.extrlLctrRqstNo) && item.extrlLctrYn === 'Y');
if(extrlList.length > 0) {
this.commonMessageService.showMsg(this.toastObj, { message: "외부강의 출장은 반드시 교육/자문신청을 함께 해주시기 바랍니다.", type: 'W'});
validate = false;
return;
}
// this.grdD0102Data.forEach((d)=> {
// if(CommonUtil.isEmpty(d.extrlLctrRqstNo) && d.extrlLctrYn === 'Y') {
// this.commonMessageService.showMsg(this.toastObj, { message: "외부강의 출장은 반드시 교육/자문신청을 함께 해주시기 바랍니다.", type: 'W'});
// validate = false;
// return;
// }
// })
if(!validate) {return}
}
// 출장 기간에 주말이 포함되어 있을 경우 협조전 발송 팝업
const bginDt = this.comDatePipe.transform(this.saveParam.bztrpBginDt);
const endDt = this.comDatePipe.transform(this.saveParam.bztrpEndDt);
const start = new Date(bginDt);
const end = new Date(endDt);
let temp = '';
while(start <= end) {
temp = start.toISOString().split('T')[0];
start.setDate(start.getDate() + 1);
if(new Date(temp).getDay() == 0 || new Date(temp).getDay() == 6) {
alert('출장 기간에 주말이 포함된 경우 총무담당자에게 협조전을 발송하고 진행해야합니다.');
break;
}
}
confirmMsg = message.com_info_approv_submit; // 결재상신 하시겠습니까?
}
const isConfirm = confirm(confirmMsg);
if (isConfirm) {
this.tempTotAmt = this.grdD0101Data.totAmt;
this.commonHttpService.post('/gaf/gaf0708/01/save.do', this.saveParam).pipe(takeUntil(this.destroy)).subscribe({
next: (response:any) => {
if (CommonUtil.isNotEmpty(response)) {
const result = response.body.results;
this.commonMessageService.showSaveMsg(this.toastObj, response);
this.saveParam.bztrpRqstNo = result.bztrpRqstNo;
this.searchParam.bztrpRqstNo = result.bztrpRqstNo;
window.postMessage('save', location.origin);
}
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
history.pushState(null, '', `${CommonUtil.getContextPath()}/#/popup/gaf/gaf070801?bztrpRqstNo=${this.saveParam.bztrpRqstNo}`);
if(misApprvStatCd === '11') {
this.commonApvService.apvDocView(this.saveParam.bztrpRqstNo);
} else {
this.getForm0101();
}
}
});
}
}
/**
* 출장신청서 삭제
* @see doTrpDelete(flag:String)
* @param crgrCnclYn
*/
deleteform0101(crgrCnclYn: string = 'N'): void {
if (CommonUtil.isNotEmpty(this.saveParam.bztrpRqstNo)) {
let confirmMsg = message.com_info_delete;
let isConfirm = false;
if ('Y' === crgrCnclYn) {
isConfirm = true;
} else {
isConfirm = confirm(confirmMsg);
}
if (isConfirm) {
this.saveParam.crgrCnclYn = crgrCnclYn;
// this.saveParam.AHFL_IDFN_ID = this.saveParam.bztrpRqstNo;
// this.saveParam.FILE_DIV_CD = this.fileDivCd;
this.commonHttpService
.post('/gaf/gaf0708/01/delete.do', this.saveParam).pipe(takeUntil(this.destroy)).subscribe({
next: (response: any) => {
//this.commonMessageService.showSaveMsg(this.toastObj, response);
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
this.btnClose();
window.postMessage('delete', location.origin);
}
});
}
}
}
/**
* 직급별 여비 조회
*
* @see doGetJobGradAmt(value:String)
* @see getJobGradeAmt(value:int)
* @see fGetBkAcctCallBack(rtn:Object)
*/
getGradClbTrex(): void {
if (CommonUtil.isNotEmpty(this.grdD0101Data)) {
/** 출장자 Data */
const btrpEmpData: Gaf0708D01Data = this.grdD0101Data;
if (CommonUtil.isNotEmpty(btrpEmpData)) {
if (
btrpEmpData.imnYn === 'Y' &&
CommonUtil.isNotEmpty(btrpEmpData.bztrpEmpNo)
) {
// 내부인일 때만 조회
//서버보낼 파라미터
const param = {
totDdNum: this.saveParam.bztrpTotDdNum ?? 0,
totLodgNum: this.saveParam.bztrpTotLodgNum ?? 0,
gradCd: btrpEmpData.bztrpGradCd ?? '',
};
let gradClbTrex: any = new Object();
this.commonHttpService
.get('/gaf/com/getGradClbTrex.do', param)
.pipe(takeUntil(this.destroy))
.subscribe(
(response) => {
if (CommonUtil.isNotEmpty(response)) {
gradClbTrex = response;
}
},
(error) => {},
() => {
// 0원 출장여부에 체크가 되어있으면 0원 처리
if (this.saveParam.bztrp0AmtYn === 'Y') {
btrpEmpData.ddMealAmt = 0; // 일일식사금액
btrpEmpData.ddLodgAmt = 0; // 일일숙박금액
btrpEmpData.atplTrfcAmt = 0; // 현지교통금액
btrpEmpData.tmpAtplTrfcAmt = 0; // 임시현지교통금액
btrpEmpData.mealAmt = 0; // 식사금액
btrpEmpData.tmpMealAmt = 0; // 임시식사금액
btrpEmpData.lodgAmt = 0; // 숙박금액
btrpEmpData.tmpLodgAmt = 0; // 임시숙박금액
btrpEmpData.airAmt = 0; // 항공금액
if (CommonUtil.isEmpty(btrpEmpData.trfcAmt)) {
btrpEmpData.trfcAmt = 0; // 교통금액
}
} else {
if (CommonUtil.isEmpty(btrpEmpData.trfcAmt)) {
btrpEmpData.trfcAmt = 0; // 교통금액
}
btrpEmpData.ddMealAmt = gradClbTrex.ddMealAmt; // 일일식사금액
btrpEmpData.ddLodgAmt = gradClbTrex.ddLodgAmt; // 일일숙박금액
btrpEmpData.atplTrfcAmt = gradClbTrex.atplTrfcAmt; // 현지교통금액
btrpEmpData.atplTrfcAmt = gradClbTrex.atplTrfcAmt; // 임시현지교통금액
btrpEmpData.mealAmt = gradClbTrex.mealAmt; // 식사금액
btrpEmpData.tmpMealAmt = gradClbTrex.mealAmt; // 임시식사금액
// btrpEmpData.LODG_AMT = gradClbTrex.LODG_AMT; // 숙박금액
// btrpEmpData.TMP_LODG_AMT = gradClbTrex.TMP_LODG_AMT; // 임시숙박금액
// ---------------------기존 정액지급에서 사후 실비정산 시 숙박비 한도 값 변경--------------------------------------------
/**
* GafUtil.toInteger의 경우 null이나 nan을 0으로 다 치환해버림
*/
let lodgAmt = 0;
if (
GafUtil.toInteger(this.saveParam.bztrpTotLodgNum) !== 0
) {
/** 임원숙박수 */
const extvLodgNum = GafUtil.toInteger(
this.saveParam.exctvLodgNum
);
if (extvLodgNum !== 0) {
lodgAmt += extvLodgNum * GafUtil.CONST_EXTV_LODG_AMT;
}
/** 서울숙박수 */
const seulLodgNum = GafUtil.toInteger(
this.saveParam.seulLodgNum
);
if (seulLodgNum !== 0) {
lodgAmt += seulLodgNum * GafUtil.CONST_SEUL_LODG_AMT;
}
/** 광역숙박수 */
const wdarLodgNum = GafUtil.toInteger(
this.saveParam.wdarLodgNum
);
if (wdarLodgNum !== 0) {
lodgAmt += wdarLodgNum * GafUtil.CONST_WDAR_LODG_AMT;
}
/** 기타지역숙박수 */
const etcAreaLodgNum = GafUtil.toInteger(
this.saveParam.etcAreaLodgNum
);
if (etcAreaLodgNum !== 0) {
lodgAmt +=
etcAreaLodgNum * GafUtil.CONST_ETC_AREA_LODG_AMT;
}
/** 친척숙박수 */
const rltvLodgNum = GafUtil.toInteger(
this.saveParam.cusnLodgNum
);
if (rltvLodgNum !== 0) {
lodgAmt += rltvLodgNum * GafUtil.CONST_RLTV_LODG_AMT;
}
/** 공동숙박수 */
const colbLodgNum = GafUtil.toInteger(
this.saveParam.colbLodgNum
);
if (colbLodgNum !== 0) {
lodgAmt += colbLodgNum * GafUtil.CONST_COLB_LODG_AMT;
}
}
btrpEmpData.lodgAmt = lodgAmt; // 숙박금액
btrpEmpData.tmpLodgAmt = lodgAmt; // 임시숙박금액
// ------------------------------------------------------------------------------------------------------
if (this.saveParam.trfcMensCd === '7') {
btrpEmpData.atplTrfcAmt = this.saveParam.bztrpTotDdNum * GafUtil.CONST_INTH_VECL_AMT; // 현지교통금액
btrpEmpData.tmpAtplTrfcAmt = this.saveParam.bztrpTotDdNum * GafUtil.CONST_INTH_VECL_AMT; // ; // 임시현지교통금액
}
}
// 출장비의 총합계를 구하고 총 출장비, 총 운영비흡수액, 총 개인지급액을 셋팅
// 총합계(교통비 + 현지교통비 + 일비 + 숙박비 + 식비)
this.calcTotAmt();
if (CommonUtil.isNotEmpty(btrpEmpData)) {
// 지급계좌정보 가져오기 PAY-002-002 : 수당계좌
// GetBkAcct("313-002",selectedRow.TRP_ID,"","PAY-002-002","",fGetBkAcctCallBack);
const param0104 = {
SPPE_DIV_CD: '313-002',
PARAM_CD: btrpEmpData.bztrpEmpNo,
EXPS_PRVD_DIV_CD: 'PAY-002-002',
};
let acctInfo: any = new Object();
this.commonHttpService
.get('/com/com0104/getBnkBactNoMap01', param0104)
.subscribe(
(response) => {
acctInfo = response;
},
(error) => {},
() => {
if (
CommonUtil.isEmpty(acctInfo.BNK_CD) ||
CommonUtil.isEmpty(acctInfo.BACT_NO) ||
CommonUtil.isEmpty(acctInfo.DPWN_NM)
) {
this.commonMessageService.showMsg(this.toastObj, {message:'경비계좌가 등록되어있지 않습니다. 급여관리자에게 문의하시기 바랍니다.', type:'W' });
/**
* AS-IS에서는 해당 데이터만 삭제하였으나
* 출장자는 1명 한정이므로 여행명세와 여비산출내역(출장자) 둘다 초기화
*
*/
// this.grdD0102Data = [];
// this.grdD0101Data = [];
// const obj : GridAddModel = {
// gridObj : this.grdD0101
// , gridData : this.grdD0101Data
// }
// this.commonGridService.gridAddRow(obj);
} else {
btrpEmpData.bnkCd = acctInfo.BNK_CD; // 은행코드
btrpEmpData.backNo = acctInfo.BACT_NO; // 계좌번호
btrpEmpData.dpwnNm = acctInfo.DPWN_NM; // 예금주
}
}
);
}
}
);
}
}
}
}
/**
* 부재자 체크
*
* @see allAbsenteeCheck(trpId:String)
* @see allGetAbstChk(value:int)
* @see doAbsenteeCheck(value:int)
* @param noticeYn
*/
getAbntAbleYn(noticeYn: string = 'N'): void {
let abntAbleYn = 'Y';
/** 출장자 Data */
const btrpEmpData: Gaf0708D01Data = this.grdD0101Data;
if (CommonUtil.isNotEmpty(btrpEmpData)) {
// 내부인만 부재자 체크 진행
const param = {
empNo: btrpEmpData.bztrpEmpNo,
bginDt: this.saveParam.bztrpBginDt,
endDt: this.saveParam.bztrpEndDt
};
this.commonHttpService.get('/gaf/com/getabntableyn', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response: any) => {
// Y:부재자아님 N:부재자
abntAbleYn = response.body.abntAbleYn;
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
if (CommonUtil.isNotEmpty(abntAbleYn) && abntAbleYn !== 'Y') {
CommonUtil.commonMsg(
this.toastObj,
'해당 직원은 설정된 출장기간에 ['+abntAbleYn+'](으)로 등재되어 있습니다.',
'W'
);
/**
* AS-IS에서는 해당 데이터만 삭제하였으나
* 출장자는 1명 한정이므로 여행명세와 여비산출내역(출장자) 둘다 초기화
*
*/
// this.grdD0102Data = [];
// this.grdD0101Data = [];
// CommonUtil.commonGridAddRow(
// this.grdD0101,
// this.grdD0101Data,
// new Gaf0708D01Data()
// );
this.calcTotAmt(); // 삭제하고난뒤 출장비 다시 계산
}
}
});
}
}
/*----------------- Baclend Handler End -----------------*/
/*----------------- Data Handler Start -----------------*/
/**
* 일반 saveParam 값 변경 처리
*
* @param value
* @param property
*/
commonSaveParamChange(value: any, property: string): void {
this.saveParam[property] = value;
}
/**
* 날짜 변경 처리
* - 출장정보 출장기간 validation
*
* @see doDayBagil('form')
* @param value
* @param property
*/
dateSaveParamChange(value: any, property: string): void {
this.commonSaveParamChange(value, property);
if (property === 'bztrpBginDt' || property === 'bztrpEndDt') {
// 출장기간 변경의 경우
// 숙박비 수정 (1박이 넘어갈 경우)
let bgnDt: string = this.saveParam.bztrpBginDt;
let endDt: string = this.saveParam.bztrpEndDt;
if (CommonUtil.isNotEmpty(bgnDt) && CommonUtil.isEmpty(endDt)) {
endDt = bgnDt;
this.commonSaveParamChange(bgnDt, 'bztrpEndDt');
}
if (CommonUtil.isNotEmpty(endDt) && CommonUtil.isEmpty(bgnDt)) {
bgnDt = endDt;
this.commonSaveParamChange(endDt, 'bztrpBginDt');
}
// 검증 처리 후 데이터 최신화
bgnDt = this.saveParam.bztrpBginDt;
endDt = this.saveParam.bztrpEndDt;
const bgnDate: Date = new Date(CommonDate.getFormattedDate(bgnDt)); // 시작일 Date 객체
const endDate: Date = new Date(CommonDate.getFormattedDate(endDt)); // 종료일 Date 객체
const oneDay: number = 1000 * 60 * 60 * 24;
const bztrpTotDdNum: number =
(endDate.getTime() - bgnDate.getTime() + oneDay) / oneDay;
this.totDay = bztrpTotDdNum; // 외부인&출장일수3일 이상일 경우 식비 직접 수정 처리때문에 추가 2022.07.11
const bztrpTotLodgNum: number = bztrpTotDdNum - 1;
// this.saveParam.bztrpTotLodgNum = bztrpTotLodgNum;
this.commonSaveParamChange(bztrpTotLodgNum, 'bztrpTotLodgNum');
this.saveParam.bztrpTotDdNum = bztrpTotDdNum;
// 출장일수가 1박이 넘을 경우 -> 하루여도 숙박가능
// if(bztrpTotDdNum > 1) {
// this.grdD0101Data.lodgAmt = this.lodgAmt;
// }else {
// this.grdD0101Data.lodgAmt = 0;
// }
//식비 set
//하루3끼로 고정 but 시내출장이면 안줌
this.calDdMealAmt(); // 하루 식비 계산
// this.grdD0101Data.mealCnt = this.saveParam.bztrpTotDdNum*3;
// this.grdD0101Data.mealAmt = this.saveParam.bztrpTotDdNum*3*GafUtil.MEAL_PAY;
if(CommonUtil.isNotEmpty(this.grdD0102Data)) {
this.grdD0102Data.forEach((d) => {
if(d.stpnCd == d.arpnCd) {
this.grdD0101Data.mealCnt = 0;
this.grdD0101Data.mealAmt = 0;
}
})
}
//일비 계산
//일반 , 공용
//this.calAtplTrfcAmtAll(); // 이제 행별로 더하니까 굳이 마스터 출장기간이 변경되었다고 일비를 계산할 필요가 없다.
//this.getGradClbTrex(); //직급별 여비조회
// 출장기간이 변경되면 출장그리드에 있는 모든출장자들의 부재자 내역을 다시 확인
// allAbsenteeCheck("TRP_ID");
this.getAbntAbleYn('N');
// 출장비의 총합계를 구하고 총 출장비, 총 운영비흡수액, 총 개인지급액을 셋팅
// doTotalAmtValue();
this.calcTotAmt();
}
}
// 일비 계산
calAtplTrfcAmt(index:any) {
let amt = 0;
// 공용여부
// const trfcMensCd = this.saveParam.trfcMensCd;
const trfcMensCd = this.grdD0102Data[index].trfcMensCd;
// 출장기간(일)
// const bztrpTotDdNum = this.saveParam.bztrpTotDdNum;
const bztrpTotDdNum = this.fnCalDate(index);
// 경유지 확인 (시내, 시외)
// 시내일 경우 시간계산
const stpnCd = this.grdD0102Data[index].stpnCd; //출발지
const arpnCd = this.grdD0102Data[index].arpnCd; //도착지
if(CommonUtil.isNotEmpty(this.grdD0102Data)) {
if(trfcMensCd == '7') { // 공용
if(stpnCd != arpnCd) {
amt = GafUtil.OUT_COMMON * Number(bztrpTotDdNum); //12500
}else {
amt = 0;
}
// 20250308 교통수단수정
// this.grdD0102Data.forEach((d) => {
// if(d.stpnCd != d.arpnCd) {
// amt = GafUtil.OUT_COMMON * Number(bztrpTotDdNum); //12500
// }else {
// amt = 0;
// }
// })
}else { // 일반
// 20250308 교통수단 수정
// this.grdD0102Data.forEach((d) => {
if(stpnCd != arpnCd) {
amt = GafUtil.OUT_NORMAL * Number(bztrpTotDdNum); //25000
}else { // 시내출장
//시간계산
const time = this.fn_calTime();
if(time < 4) {
amt = GafUtil.IN_NORMAL_LESS * Number(bztrpTotDdNum); //10000
}else {
amt = GafUtil.IN_NORMAL_MORE * Number(bztrpTotDdNum); //20000
}
// 20250305
// if(this.grdD0102Data.length === 1 && d.extrlLctrYn === 'Y') {
// amt = 0;
// }
// if(this.saveParam.bztrpShpCd === '5') { // 외부강의
// amt = 0;
// }
}
// })
}
}else {
amt = 0;
}
console.log("일비계산", amt);
this.grdD0101Data.atplTrfcAmt = GafUtil.toInteger(this.grdD0101Data.atplTrfcAmt) + GafUtil.toInteger(amt);
console.log("최종일비계산", this.grdD0101Data.atplTrfcAmt);
}
// 전체일비 계산
calAtplTrfcAmtAll() {
let amt = 0;
for(let index = 0; index <this.grdD0102Data.length; index++) {
// 공용여부
// const trfcMensCd = this.saveParam.trfcMensCd;
const trfcMensCd = this.grdD0102Data[index].trfcMensCd;
// 출장기간(일)
// const bztrpTotDdNum = this.saveParam.bztrpTotDdNum;
const bztrpTotDdNum = this.fnCalDate(index);
// 경유지 확인 (시내, 시외)
// 시내일 경우 시간계산
const stpnCd = this.grdD0102Data[index].stpnCd; //출발지
const arpnCd = this.grdD0102Data[index].arpnCd; //도착지
if(CommonUtil.isNotEmpty(this.grdD0102Data)) {
if(trfcMensCd == '7') { // 공용
if(stpnCd != arpnCd) {
amt = GafUtil.OUT_COMMON * Number(bztrpTotDdNum); //12500
}else {
amt = 0;
}
// 20250308 교통수단수정
// this.grdD0102Data.forEach((d) => {
// if(d.stpnCd != d.arpnCd) {
// amt = GafUtil.OUT_COMMON * Number(bztrpTotDdNum); //12500
// }else {
// amt = 0;
// }
// })
}else { // 일반
// 20250308 교통수단 수정
// this.grdD0102Data.forEach((d) => {
if(stpnCd != arpnCd) {
amt = GafUtil.OUT_NORMAL * Number(bztrpTotDdNum); //25000
}else { // 시내출장
//시간계산
const time = this.fn_calTime();
if(time < 4) {
amt = GafUtil.IN_NORMAL_LESS * Number(bztrpTotDdNum); //10000
}else {
amt = GafUtil.IN_NORMAL_MORE * Number(bztrpTotDdNum); //20000
}
// 20250305
// if(this.grdD0102Data.length === 1 && d.extrlLctrYn === 'Y') {
// amt = 0;
// }
// if(this.saveParam.bztrpShpCd === '5') { // 외부강의
// amt = 0;
// }
}
// })
}
}else {
amt = 0;
}
this.grdD0101Data.atplTrfcAmt = GafUtil.toInteger(this.grdD0101Data.atplTrfcAmt) + GafUtil.toInteger(amt);
}
}
/**
* 출장박수 변경 이벤트 처리
*/
bztrpTotLodgNumChange(event: any): void {
let value = event.value;
const bztrpTotDdNum = this.saveParam.bztrpTotDdNum;
value = Math.floor(value);
if(value > bztrpTotDdNum) {
this.saveParam.bztrpTotLodgNum = bztrpTotDdNum - 1;
this.commonMessageService.showMsg(this.toastObj, { message : '출장일수를 확인해주세요.', type : 'W', title : '경고 알람' });
}else {
this.saveParam.bztrpTotLodgNum = value;
}
this.calcTotAmt();
}
/**
* dropdownlist saveParam 값 변경 처리
*
* @param event
* @param property
*/
dropdownSaveParamChange(event: any, property: string): void {
//if (CommonUtil.isNotEmpty(event.previousItemData)) {
// this.commonSaveParamChange(event.value, property);
this.saveParam[property] = event.value;
//}
if(property === 'bztrpShpCd') {
// 외부강의가 아닐경우 체크 해제 -> 기존 교육신청, 외부강의 여부 삭제 필요
if(event.value !== '5') {
this.grdD0102Data = JSON.parse(JSON.stringify(this.copyLodgD0102)); //숙박비그리드 복사
this.grdD0102Data.forEach((d) => {
d.extrlLctrYn = 'N'; // 외부강의 여부
})
} else { // 외부강의 선택시
this.grdD0102Data.forEach((d) => {
if(CommonUtil.isNotEmpty(d.extrlLctrRqstNo)) { // 외부강의 pk가 있으면 외부강의 여부 Y로
d.extrlLctrYn = 'Y'; // 외부강의 여부
}
})
}
}
}
/** 교육신청 팝업 */
fnEduPopup(args: any, index: number) {
let obj;
obj = {
url: '/popup/edu/edu050101',
param: { lnkCd: '2', rqstNo: this.grdD0102Data[index].extrlLctrRqstNo
, lnkDcmtNo: this.saveParam.bztrpRqstNo , lnkDcmtSn: this.grdD0102Data[index].sn}, //구분값 1휴가,2출장
width: 1300,
height: 800,
target: 'edu050101_new',
};
let crud = '';
if(CommonUtil.isEmpty(this.grdD0102Data[index].extrlLctrRqstNo)) {
crud = 'C';
}
const popup = CommonUtil.openWindowPopup(obj);
if(popup) {
this.unlistener = this.renderer2.listen(popup, 'message', (e) => {
if (e.origin === location.origin && CommonUtil.isNotEmpty(e.data.eduSave)) { // 교육pk 리턴
// TODO 출장 테이블에 교육pk update 해주기
const extrlLctrRqstNo = e.data.eduSave;
this.grdD0102Data[index].extrlLctrRqstNo = extrlLctrRqstNo;
const param = {extrlLctrRqstNo:extrlLctrRqstNo, sn: this.grdD0102Data[index].sn, bztrpRqstNo:this.saveParam.bztrpRqstNo, extrlLctrYn:this.grdD0102Data[index].extrlLctrYn};
this.fnEduUpdate(param);
if(crud != 'C') {
this.fnGetMvList(); // 외부강의 저장후 지원금액 차감
}
} else if(e.origin === location.origin && e.data === 'delete') {
this.commonMessageService.showMsg(this.toastObj, { message: message.com_succ_delete});
this.grdD0102Data[index].extrlLctrRqstNo = '';
const param = {extrlLctrRqstNo:this.grdD0102Data[index].extrlLctrRqstNo, sn: this.grdD0102Data[index].sn, bztrpRqstNo:this.saveParam.bztrpRqstNo, extrlLctrYn:'N'};
this.fnEduUpdate(param);
}
});
}
}
// 외부강의 저장후 지원금액 불러오기 위한 함수
fnGetMvList() {
this.commonHttpService.get('/gaf/gaf0708/01/getmvlist.do', this.searchParam).pipe(takeUntil(this.destroy)).subscribe({
next: (response:any) => {
const list = response.body;
const grdList: GridViewModel = {
gridData: list,
};
this.grdD0102Data = this.commonGridService.gridList(grdList); // 경유지 목록 리로딩
console.log(this.grdD0102Data);
let spptTrfc = 0; // 지원교통비
let spptMeal = 0; // 지원식비
let spptDd = 0; // 지원일비
const grdD0101Data = this.grdD0101Data;
const nowMealAmt = grdD0101Data.mealAmt + grdD0101Data?.xcldChfdAmt ?? 0; // 식비 - 기존제외식비 = 현재 제외가능한 금액
const nowAtplAmt = grdD0101Data.atplTrfcAmt + grdD0101Data?.xcldCpdAmt ?? 0; // 일비 - 기존제외일비 = 현재 제외가능한 금액
list.forEach((item:any)=>{
// 한 행의 지원 교통비가 전체 교통비보다 많으면 그냥 전체 교통비만큼만 제외하는거
// 마이너스 처리는 안함!
if(item.supptTrfcAmt > item.trfcAmt) {
spptTrfc += GafUtil.toInteger(item.trfcAmt);
}else {
spptTrfc += GafUtil.toInteger(item.supptTrfcAmt);
}
// 한 행의 지원 식비가 하루 최대식비(30000원) 보다 많으면 그냥 하루 최대 식비만큼만
// 마이너스 처리는 안함!
let tempMealAmt = 0;
if(item.supptFoodEpnsAmt > GafUtil.MEAL_PAY*3) {
tempMealAmt = GafUtil.toInteger(GafUtil.MEAL_PAY*3);
}else {
tempMealAmt = GafUtil.toInteger(item.supptFoodEpnsAmt);
}
if(nowMealAmt < tempMealAmt) {
spptMeal += nowMealAmt;
}else {
spptMeal += tempMealAmt;
}
// 일비 최대 25000원까지 지원가능
// 마이너스 처리는 안함!
let tempCpdAmt = 0;
if(item.supptCpdAmt > GafUtil.OUT_NORMAL) {
tempCpdAmt = GafUtil.toInteger(GafUtil.OUT_NORMAL);
}else {
tempCpdAmt = GafUtil.toInteger(item.supptCpdAmt);
}
if(nowAtplAmt < tempCpdAmt) {
spptDd += nowAtplAmt;
}else {
spptDd += tempCpdAmt;
}
})
grdD0101Data.xcldTrfcAmt = -spptTrfc;
grdD0101Data.xcldCpdAmt = -spptDd;
grdD0101Data.xcldChfdAmt = -spptMeal;
console.log(spptTrfc, spptMeal, spptDd);
console.log('결과',this.grdD0101Data);
this.calcTotAmt(); // 출장자내역 합계 계산
this.fnXcldUpdate(grdD0101Data); // 제외금액 저장
}
,error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
}
})
}
/* 제외금액 저장 */
fnXcldUpdate(param:any) {
this.commonHttpService.post('/gaf/gaf0708/01/updatebztrpxcld.do', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response:any) => {
//this.commonMessageService.showSaveMsg(this.toastObj, response);
}
,error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
}
,complete: () => {
}
})
}
/** 외부강의 pk 저장 */
fnEduUpdate(param:any) {
this.commonHttpService.post('/gaf/gaf0708/01/updateExtrlNo.do', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response:any) => {
//this.commonMessageService.showSaveMsg(this.toastObj, response);
this.fnGetMvList(); // 외부강의 저장후 지원금액 차감
}
,error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
}
})
}
/**
* 다이얼로그 검색 콜백 이벤트 처리
* @param event
* @param property
*/
dialogSaveParamChange(event: any, property: string): void {
let param: any = {};
if ('empNo' === property) {
// 신청자 검색
param = {
empNo: event?.empNo ?? '',
EMP_NM: event?.NAME ?? '',
DEPT_CD: event?.DEPT_CD ?? '',
DEPT_NM: event?.DEPT_NM ?? '',
GRAD_CD: event?.GRAD_CD ?? '',
GRAD_NM: event?.GRAD_NM ?? '',
};
if (CommonUtil.isEmpty(param.empNo)) {
Object.keys(param).forEach((key) => {
param[key] = '';
});
}
} else if ('bdgCd' === property) {
// 예산과목 검색
//console.log("예산",event);
if(CommonUtil.isNotEmpty(event)) {
// 첫번째 항목이 예산과목
this.saveParam.bdgCd = event[0].bdgCd; // 예산코드
this.saveParam.bdgNm = event[0].bdgNm; // 예산명
this.saveParam.bdgRspsrEmpNo = event[0].rspsrEmpNo; //예산책임자
this.saveParam.bdgDeptCd = event[0].supvDeptCd; //예산부서코드
this.saveParam.bizEndDt = event[0].endDt; //사업종료일자
// 두번째 항목이 비용항목
this.saveParam.eptmCd = event[1].eptmCd; // 비목코드
this.saveParam.eptmNm = event[1].eptmNm; // 비목명
this.saveParam.acctCd = event[1].acctCd; // 계정코드
this.saveParam.bdgLmitAmt = event[1].blncAmt; //예산한도금액 잔액
}
param = {
bdgCd: event?.bdgCd ?? '', // 예산코드
bdgNm: event?.bdgNm ?? '', // 예산명
eptmCd: event?.eptmCd ?? '', // 비목코드
eptmNm: event?.eptmNm ?? '', // 비목명
execdiv: event?.execdiv ?? '', // 이지바로 집행구분
exenmiv: event?.exenmiv ?? '', // 이지바로 집행구분
bdgRspnr_emp_no: event?.rspnrEmpNo ?? '', // 예산책임자직원번호
bdgRspnr_emp_nm: event?.rspnrEmpNm ?? '', // 예산책임자직원번호
bizEnd_dt: event?.bizEndDt ?? '', // 사업종료일자
rcmsYn: event?.rcmsYn ?? '', // rcms 과제 여부
};
if (CommonUtil.isEmpty(param.bdgCd)) {
Object.keys(param).forEach((key) => {
param[key] = '';
});
} else {
// RCMS 과제 여부 체크
if (param.rcmsYn === 'Y') {
// RCMS 과제 dialog open
alert('해당예산은 RCMS 과제입니다.');
}
}
}
this.commonSaveParamChange(param, '');
}
/**
* 0원 출장 체크박스 클릭
*
* - 별도항목 설정하여 일괄 적용 가능토록 요청(원차량 이용과 동일)
*
* @see doZeroChk()
* @param value
*/
bztrp0AmtYnChange(value: any): void {
this.commonSaveParamChange(value, 'bztrp0AmtYn');
/** 출장자 Data */
const bztrpEmpData = this.grdD0101Data;
if (CommonUtil.isNotEmpty(bztrpEmpData)) {
if (value === 'Y') {
// 여비를 모두 0원처리 한다.
bztrpEmpData.trfcAmt = 0; // 교통금액
bztrpEmpData.tmpAtplTrfcAmt = 0; // 임시현지교통금액
bztrpEmpData.airAmt = 0; // 항공금액
bztrpEmpData.atplTrfcAmt = 0; // 현지교통금액
bztrpEmpData.tmpLodgAmt = 0; // 임시숙박금액
bztrpEmpData.lodgAmt = 0; // 숙박금액
bztrpEmpData.tmpMealAmt = 0; // 임시식사금액
bztrpEmpData.mealAmt = 0; // 식사금액
bztrpEmpData.totAmt = 0; // 총합계금액
bztrpEmpData.persProvdAmt = 0;
bztrpEmpData.ddMealAmt = 0; // 일일식사금액
bztrpEmpData.ddLodgAmt = 0; // 일일숙박금액
bztrpEmpData.mealCnt = 0; // n식
// 여행명세 요금을 0원처리 한다.
if (CommonUtil.isNotEmpty(this.grdD0102Data)) {
for (let index = 0; index < this.grdD0102Data.length; index++) {
this.grdD0102Data[index].trfcAmt = 0;
this.grdD0102Data[index].rmchrAmt = 0;
//this.grdD0102Data[index].lodgDdNum = 0; //숙박일수 -> 0원 출장이여도 숙박을 할 수 도 있음.
}
}
} else {
// 식비
this.calDdMealAmt(); // 하루 식비계산
//this.getGradClbTrex(); // 직급별 여비가져오기
// 여행명세(경유지) 원복
//this.grdD0102Data = JSON.parse(JSON
for (let index = 0; index < this.copyLodgD0102.length; index++) {
const rmchrAmt = GafUtil.toInteger(this.grdD0102Data[index].nstLodgAmt ?? (this.copyLodgD0102[index].rmchrAmt > 0 ? GafUtil.toInteger(this.copyLodgD0102[index].rmchrAmt) / GafUtil.toInteger(this.copyLodgD0102[index].lodgDdNum) : 0));
const lodgDdNum = GafUtil.toInteger(this.grdD0102Data[index].lodgDdNum == 0 ? 1 : this.grdD0102Data[index].lodgDdNum);
if(this.grdD0102Data[index].drmtLodgYn == 'Y'
// || this.grdD0102Data[index].extrlLctrYn == 'Y' //20250305
) {
this.grdD0102Data[index].rmchrAmt = 0;
//this.grdD0102Data[index].lodgDdNum = 0;
}else {
this.grdD0102Data[index].rmchrAmt = rmchrAmt * lodgDdNum;
}
}
for (let index = 0; index < this.copyGrdD0102.length; index++) {
const trfcAmt = this.copyGrdD0102[index].trfcAmt;
// if(this.grdD0102Data[index].extrlLctrYn == 'Y') { //20250305
// this.grdD0102Data[index].trfcAmt = 0;
// }else {
this.grdD0102Data[index].trfcAmt = trfcAmt;
// }
}
// 여행명세 요금을 여비산출내역 교통비로 복사
let pv = 0;
let pv2 = 0;
for (let index = 0; index < this.copyGrdD0102.length; index++) {
if(bztrpEmpData.bztrpEmpNo === this.copyGrdD0102[index].bztrpEmpNo) {
pv += this.copyGrdD0102[index].trfcAmt;
pv2 += this.copyGrdD0102[index].rmchrAmt;
}
}
bztrpEmpData.trfcAmt = pv;
bztrpEmpData.lodgAmt = pv2;
// bztrpEmpData.trfcAmt = this.grdD0102Data
// .filter((f) => bztrpEmpData.bztrpEmpNo === f.bztrpEmpNo)
// .reduce((pv: number, cv: Gaf0708D02Data) => {
// return pv + Number(cv.trfcAmt);
// }, 0);
// 출장자의 여행명세에서 교통금액을 연산처리하여 출장자의 교통금액에 저장
// 여행명세 요금을 되돌린다.
// this.grdD0102Data.forEach((d) => {
// d.trfcAmt = d.tmpTrfcAmt;
// });
//this.copyGrdD0102 = JSON.parse(JSON.stringify(this.grdD0102Data));
this.calcGrdD0102AmtChange();
}
}
}
/**
* 교통수단 변경
*/
trfcMensCdChange(value: any, index:any): void {
this.commonSaveParamChange(value, 'trfcMensCd');
/** 출장자 Data */
const btrpEmpData: Gaf0708D01Data = this.grdD0101Data;
if (CommonUtil.isNotEmpty(btrpEmpData)) {
if (value === '7') { //공용
// 교통비 0원 처리
this.grdD0102Data[index].trfcAmt = 0;
// 교통비 0원 처리
// btrpEmpData.trfcAmt = 0;
// this.grdD0102Data.forEach((d) => {
// d.trfcAmt = 0;
// });
this.calAtplTrfcAmt(index); // 일비 계산
} else if(value === '0'){ // 일반
//nst 갔다오기 -> 교통비, 숙박비
this.fn_getNstInfoForMv(index);
// 일비계산
this.calAtplTrfcAmt(index);
// this.grdD0102Data.forEach((d, index) => {
// d.trfcAmt = CommonUtil.isEmpty(this.copyGrdD0102[index].nstTrfcAmt) ? this.copyGrdD0102[index].trfcAmt : this.copyGrdD0102[index].nstTrfcAmt;
// });
// 교통비 계산
// this.grdD0102Data
// .forEach((data: Gaf0708D02Data) => {
// data.trfcAmt = data.tmpTrfcAmt;
// });
this.commonSaveParamChange('N', 'instVeclUseYn');
this.commonSaveParamChange('N', 'etcVeclUseYn');
this.commonSaveParamChange('', 'etcVeclUseRsnCntn');
this.commonSaveParamChange('', 'wkndInthVeclUseYn');
//this.getGradClbTrex();
}
// 여행명세 그리드에서 출장자의 교통비를 합산하여 출장자내역 교통비에 셋팅
this.calcGrdD0101TrfcAmt();
// 출장비의 총합계를 구하고 총 출장비, 총 운영비흡수액, 총 개인지급액을 셋팅
this.calcTotAmt();
}
// this.fnCalVecl();
// // 여행명세 그리드에서 출장자의 교통비를 합산하여 출장자내역 교통비에 셋팅
// this.calcGrdD0101TrfcAmt();
// // 출장비의 총합계를 구하고 총 출장비, 총 운영비흡수액, 총 개인지급액을 셋팅
// this.calcTotAmt();
}
/**
* 공제 회수 변경 이벤트 처리
*/
ddctNumChange(event: any, property: string): void {
const value = Math.floor(event);
this.saveParam[property] = value;
if(property === 'vsitInstMealInclNum') { // 방문기관식사공제
if(value > 0) {
this.saveParam.vsitInstMealInclYn = 'Y';
}else {
this.saveParam.vsitInstMealInclYn = 'N';
}
}else if(property === 'vsitInstLodgInclNum') { //방문기관숙박공제
if(value > 0) {
this.saveParam.vsitInstLodgInclYn = 'Y';
}else {
this.saveParam.vsitInstLodgInclYn = 'N';
}
}
this.calcTotAmt('ddct');
}
/**
* 차량 사용 여부 변경 이벤트 처리
* - INST_VECL_USE_YN: 기관차량사용여부
* - ETC_VECL_USE_YN: 기타차량사용여부
* @param value
* @param property
*/
veclUseYnChange(value: any, property: string): void {
this.commonSaveParamChange(value, property);
this.calcTotAmt();
}
/**
* 출장일수안내 다이얼로그 호출
*
* @see showPop()
*/
openGafBtrpNotice(): void {
const dialogConfig = new CommonMatDialogConfig();
dialogConfig.width = '700px';
dialogConfig.height = '550px';
dialogConfig.panelClass = ['modal-center'];
dialogConfig.data = { PGM_ID: 'gaf0708' };
this.dialog.open(Gaf070810Component, dialogConfig);
}
/**
* NST API 연동 교통금액 조회
*
* @param index
*/
openNstApiTrfcAmt(index: number): void {
this.searchParam.startCityCode = this.grdD0102Data[index].stpnCd;
this.searchParam.endCityCode = this.grdD0102Data[index].arpnCd;
const chaeDivCd = this.grdD0102Data[index].chaeDivCd;
let respObj: any;
this.commonHttpService.get('/gaf/com/getnstpath.do', this.searchParam).pipe(takeUntil(this.destroy)).subscribe({
next: (response : any) => {
if(CommonUtil.isNotEmpty(response.body)) {
respObj = response.body;
} else {
this.commonMessageService.showSaveMsg(this.toastObj, response); // Exception 메시지 처리
}
},
error: () => {
this.commonMessageService.showMsg(
this.toastObj,
{message:'NST에서 해당 경로의 운임비를 조회하지 못 하였습니다. <br/> 직접 입력해주세요.',
type:'W'}
);
},
complete: () => {
if(chaeDivCd === 'A') {
this.grdD0102Data[index].trfcAmt = respObj.payment*2; // 요금
}else {
this.grdD0102Data[index].trfcAmt = respObj.payment
}
this.grdD0102Data[index].rmchrAmt = respObj.rmchrAmt; //숙박비
}
});
}
/**
* 담당자 취소 사유 입력 다이얼로그 호출
*/
openCrgrCnclDialog(): void {/*
const dialogConfig = new CommonMatDialogConfig();
dialogConfig.width = '700px';
dialogConfig.height = '240px';
dialogConfig.panelClass = ['modal-center'];
const dialogRef = this.dialog.open(Gaf070813Component, dialogConfig);
dialogRef
.afterClosed()
.pipe(takeUntil(this.destroy))
.subscribe((res) => {
this.saveParam.CRGR_CNCL_YN = 'Y';
this.saveParam.CRGR_CNCL_RSN_CNTN = res.CRGR_CNCL_RSN_CNTN;
this.deleteform0101('Y');
}); */
}
/**
* 정보기기 반출 시 유의사항 다이얼로그 호출
*
*/
openGafAsetOutYn(): void {
const dialogConfig = new CommonMatDialogConfig();
dialogConfig.width = '700px';
dialogConfig.height = '500px';
dialogConfig.panelClass = ['modal-center'];
this.dialog.open(GafAsetOutYnYComponent, dialogConfig);
}
/**
* grdD0102의 요금이 바뀔때 출장비 자동계산
*
* @see amtChg()
*/
calcGrdD0102AmtChange(): void {
this.calcGrdD0101TrfcAmt(); // 여행명세 그리드에서 출장자의 교통비를 합산하여 출장자내역 교통비에 셋팅
}
/**
* 출장자 이동 내역(여행명세) 중 교통별 구분 금액 구해서 출장자 내역의 교통비 합계에 대이터 넣기
*
* @see doTraffAmtMakeValue()
*/
calcGrdD0101TrfcAmt(): void {
// if (CommonUtil.isNotEmpty(this.grdD0102Data)) {
// 일비 계산
this.calAtplTrfcAmtAll();
/**
* 원내차량 이용일 경우 (교통비 0원)
* NST 연계 추가
* 교통구분이 육로, NST인 데이터를 초기화
*/
if (this.saveParam.trfcMensCd === '7') {
this.grdD0102Data.forEach((d: Gaf0708D02Data) => {
d.trfcAmt = 0;
});
}
/**
* 0원 출장
* NST 연계 추가
* 교통비 초기화
*/
if (this.saveParam.bztrp0AmtYn === 'Y') {
this.grdD0102Data.forEach((d: Gaf0708D02Data) => {
d.trfcAmt = 0;
d.rmchrAmt = 0;
});
}
// for (let index = 0; index < this.grdD0102Data.length; index++) {
// this.fnCalDrmtLodgYn(index); //기숙사여부
// this.fnCalLctr(index); //외부강의
// }
/** 교통금액 */
let trfcAmt = 0;
/** 항공금액 */
let airAmt = 0;
/** 숙박비 */
let rmchrAmt = 0;
// 교통구분이 항공이 아닌 것들의 합
trfcAmt = this.grdD0102Data
.filter((f: Gaf0708D02Data) => '807-003' !== f.trfcDivCd)
.reduce((pv: number, cv: Gaf0708D02Data) => {
return pv + Number(cv.trfcAmt ?? 0);
}, 0);
// 교통구분이 항공인 것들의 합.
airAmt = this.grdD0102Data
.filter((f: Gaf0708D02Data) => '807-003' === f.trfcDivCd)
.reduce((pv: number, cv: Gaf0708D02Data) => {
return pv + Number(cv.trfcAmt ?? 0);
}, 0);
// 여행명세(경유지) 숙박비 합
// if(this.saveParam.bztrpTotDdNum > 1) {
rmchrAmt = this.grdD0102Data.reduce((pv: number, cv: Gaf0708D02Data) => {
return pv + Number(cv.rmchrAmt ?? 0);
}, 0);
// }
/** 출장자 Data */
const bztrpEmpData: Gaf0708D01Data = this.grdD0101Data;
if (CommonUtil.isNotEmpty(bztrpEmpData)) {
if (this.saveParam.bztrp0AmtYn === 'Y') {
// 0원 출장일 떄
bztrpEmpData.trfcAmt = 0;
bztrpEmpData.airAmt = 0;
bztrpEmpData.lodgAmt = 0;
bztrpEmpData.mealAmt = 0;
bztrpEmpData.atplTrfcAmt = 0;
} else {
// 0원 출장이 아닐 떄
bztrpEmpData.trfcAmt = trfcAmt;
bztrpEmpData.airAmt = airAmt;
bztrpEmpData.lodgAmt = rmchrAmt;
//bztrpEmpData.atplTrfcAmt = atplTrfcAmt;
}
}
// }
// 여행명세 데이터가 있을 때
//console.log("여행명세데이터",this.grdD0102Data);
this.calcTotAmt(); // 출장비의 총합계를 구하고 총 출장비, 총 운영비흡수액, 총 개인지급액을 셋팅
}
/**
* 출장내용 그리드 행추가
* grdD0103 값 변경 처리
*
* @param args
* @param index
* @param column
*/
grdD0103Change(args: any, index: number, column: string): void {
let value = args;
if(CommonUtil.isNotEmpty(args)) {
this.grdD0103Data[index][column] = value;
}
let bginDt = '';
let endDt = '';
if('bginDt' === column || 'endDt' === column) {
bginDt = this.grdD0103Data[index].bginDt;
endDt = this.grdD0103Data[index].endDt;
}
if(CommonUtil.isNotEmpty(bginDt) && CommonUtil.isNotEmpty(endDt)) {
// 날짜역전 검증
if(bginDt > endDt) {
this.commonMessageService.showMsg(this.toastObj, { message : message.puc_warn_date_compare.replace('{0}', '시작일자').replace('{1}', '종료일자').replace('{2}', '클'), type : 'W', title : '경고 알람' }); // 시작일자는 종료일자 보다 클 수 없습니다.
this.grdD0103Data[index][column] = '';
return;
}
const bztrpBginDt = this.saveParam.bztrpBginDt;
const bztrpEndDt = this.saveParam.bztrpEndDt;
if(bginDt < bztrpBginDt || endDt > bztrpEndDt) {
this.commonMessageService.showMsg(this.toastObj, { message : '해당 일자가 출장기간에 포함되지 않습니다.', type : 'W', title : '경고 알람' });
this.grdD0103Data[index][column] = '';
return;
}
const dy = GafUtil.getDayName(bginDt)+'~'+GafUtil.getDayName(endDt)
this.grdD0103Data[index].dy = dy;
}
const crudgrid: GridUpdateModel = {
gridData: this.grdD0103Data,
value: value,
index: index,
column: column
};
this.commonGridService.gridCrudUpdate(crudgrid);
}
/**
* 내외부인 다이얼로그 Component 조회
*
* @param imnYn \
* @returns
*/
getImnYnDComponent(imnYn: string = 'Y'): any {
if (imnYn === 'Y') {
return this.empDComponent;
} else {
return this.gafExtrDComponent;
}
}
/**
* 내외부인 다이얼로그 Width 조회
*
* @param imnYn \
* @returns
*/
getImnYnDWidth(imnYn: string = 'Y'): any {
if (imnYn === 'Y') {
return this.empDWidth;
} else {
return this.gafExtrDWidth;
}
}
/**
* 내외부인 다이얼로그 Height 조회
*
* @param imnYn \
* @returns
*/
getImnYnDHeight(imnYn: string = 'Y'): any {
if (imnYn === 'Y') {
return this.empDHeight;
} else {
return this.gafExtrDHeight;
}
}
/**
* grdD0101 값 변경 처리
*
* @see amtCalcu()
* @param event
* @param index
* @param property
*/
grdD0101Change(event: any, property: string): void {
if (
property === 'atplTrfcAmt' || // 일비
property === 'lodgAmt' || // 숙박비
property === 'mealAmt' || // 식비
property === 'trfcAmt' // 교통비
|| property === 'xcldChfdAmt' // 제외식비
|| property === 'xcldCpdAmt' // 제외일비
|| property === 'xcldTrfcAmt' // 제외교통비
) {
//if(property === 'MEAL_AMT') this.mealAmt = event;
this.grdD0101Data[property] = event;
this.calcTotAmt(); // 비용 총합계 계산
}else if(property === 'sapvApntYn') { // 대결지정
this.grdD0101Data[property] = event.value;
}
}
/**
* grdD0101 출장자 변경 이벤트 처리
*
* @see clickEmpGridPopup(value:String="")
* @see enterEmpGridPopup(event:CommonEvent)
* @see popupExtrPers()
* @param event
* @param index
*/
grdD0101BtrpNmChange(event: any, index: number): void {
// 기존정보 초기화
/** 출장직원번호 BTRP_EMP_NO */
let bztrpEmpNo = '';
/** 출장자 BTRP_EMP_NM */
let bztrpEmpNm = '';
/** 출장부서코드 BTRP_DEPT_CD */
let bztrpDeptCd = '';
/** 출장부서 BTRP_DEPT_NM */
let bztrpDeptNm = '';
/** 출장직급코드 BTRP_GRAD_CD */
let bztrpGradCd = '';
/** 출장직급 BTRP_GRAD_NM */
let bztrpGradNm = '';
/** 출장직급코드 BTRP_POSI_CD */
let bztrpPosiCd = '';
/** 외부인소속기관명 OUTR_PSTN_INST_NM */
let outrPstnInstNm = '';
/** 외부인직위명 OUTR_POSI_NM */
let outrPosiNm = '';
/** 은행코드 BNK_CD */
let bnkCd = '';
/** 예금주명 DPWN_NM */
let dpownNm = '';
/** 계좌번호 BACT_NO */
let bactNo = '';
/** 계좌번호 */
let bztrpBactNo = '';
/** 은행코드 */
let bztrpBankCd = '';
/** 사업장코드 */
let bplcCd = '';
//여비등급코드
let trexGrdCd = '';
//신분등급코드
let scpsGrdCd = '';
if (CommonUtil.isNotEmpty(event)) {
// callback으로 전달 받은 데이터 매핑
if (this.grdD0101Data.imnYn === 'Y') {
// 내부인
if (CommonUtil.isNotEmpty(event.empNo)) {
console.log("내부인",event);
bztrpEmpNo = event.empNo;
bztrpEmpNm = event.name;
bztrpDeptCd = event.deptCd;
bztrpDeptNm = event.deptNm;
bztrpGradCd = event.gradCd;
bztrpGradNm = event.gradNm;
bztrpPosiCd = event.posiCd;
bztrpBactNo = event.bztrpBactNo;
bztrpBankCd = event.bztrpBankCd;
dpownNm = event.name;
bplcCd = event.wrkAreaCd;
trexGrdCd = event.gradDivCd; // 여비등급
scpsGrdCd = event.scpsGrdCd; // 신분등급
if( CommonUtil.isEmpty(bztrpBactNo) ||
CommonUtil.isEmpty(bztrpBankCd)
) {
this.commonMessageService.showMsg(this.toastObj, { message: '경비계좌가 등록되어있지 않습니다. 급여관리자에게 문의하시기 바랍니다.', type: 'W'});
bztrpEmpNo = '';
bztrpEmpNm = '';
bztrpDeptCd = '';
bztrpDeptNm = '';
bztrpGradCd = '';
bztrpGradNm = '';
bztrpPosiCd = '';
bztrpBactNo = '';
bztrpBankCd = '';
dpownNm = '';
bplcCd = '';
trexGrdCd = '';
scpsGrdCd = '';
//return;
}
}
}
}
// 데이터 매핑 결과가 없음 그대로 empty string으로 치환
// const crudgrid: GridUpdateModel = {
// gridData: this.grdD0101Data,
// value: bztrpEmpNo,
// index: index,
// column: 'bztrpEmpNo'
// }
//update crud
// this.commonGridService.gridCrudUpdate(crudgrid);
this.grdD0101Data.bztrpEmpNm = bztrpEmpNm;
this.grdD0101Data.bztrpDeptCd = bztrpDeptCd;
this.grdD0101Data.bztrpDeptNm = bztrpDeptNm;
this.grdD0101Data.bztrpGradCd = bztrpGradCd;
this.grdD0101Data.bztrpGradNm = bztrpGradNm;
this.grdD0101Data.bztrpPosiCd = bztrpPosiCd;
this.grdD0101Data.outrPosiNm = outrPosiNm;
this.grdD0101Data.outrPstnInstNm = outrPstnInstNm;
this.grdD0101Data.bnkCd = bnkCd;
this.grdD0101Data.dpownNm = dpownNm;
this.grdD0101Data.bankCd = bztrpBankCd; //은행코드
this.grdD0101Data.bplcCd = bplcCd; //사업장코드
// 변경 후 처리
if (this.grdD0101Data.imnYn === 'Y') {
// 내부인
this.getAbntAbleYn('Y'); // 부재자 체크
}
}
/**
* 여비등급 조회
*/
fn_trexInfo() {
const param = {empNo:this.userInfo.empNo}
this.commonHttpService.get('/per/dialog/getemplist.do', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response: any) => {
if(CommonUtil.isNotEmpty(response.body)) {
const resultList = response.body;
if(CommonUtil.isNotEmpty(resultList[0].bztrpBactNo)) {
this.grdD0101Data.dpownNm = resultList[0].name;
this.grdD0101Data.bztrpEmpNo = resultList[0].empNo;
this.grdD0101Data.bztrpEmpNm = resultList[0].name;
this.grdD0101Data.bztrpDeptCd = resultList[0].deptCd;
this.grdD0101Data.bztrpDeptNm = resultList[0].deptNm;
this.grdD0101Data.bztrpGradCd = resultList[0].gradCd;
this.grdD0101Data.bztrpGradNm = resultList[0].gradNm;
this.grdD0101Data.bztrpPosiCd = resultList[0].posiCd;
this.grdD0101Data.bankCd = resultList[0].bztrpBankCd;
this.grdD0101Data.dpownNm = resultList[0].name;
this.grdD0101Data.bplcCd = resultList[0].wrkAreaCd;
this.grdD0101Data.trexGrdCd = resultList[0].gradDivCd; // 여비등급
this.grdD0101Data.scpsGrdCd = resultList[0].scpsGrdCd; // 신분등급
}else {
this.commonMessageService.showMsg(this.toastObj, {message:'경비계좌가 등록되어있지 않습니다. 급여관리자에게 문의하시기 바랍니다.', type:'W' });
return;
}
}
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => { console.log(this.grdD0101Data); }
})
}
/**
* grdD0101 대리인 변경 이벤트 처리
*
* @see clickAgyGridPopup(value:String="")
* @see enterAgyGridPopup(event:CommonEvent)
* @see getAbstChkforAgt(value:int)
* @param event
* @param index
*/
grdD0101AngtNmChange(event: any): void {
/** 대리인직원번호 angtEmpNo */
let angtEmpNo = '';
/** 대리인 angtEmpNm */
let angtEmpNm = '';
/** 대리인 ANGT_DEPT_CD */
let angtDeptCd = '';
/** 대리인직급코드 ANGT_GRAD_CD */
let angtGradCd = '';
/** 대결지정여부 RPRV_APNT_YN */
let rprvApntYn = 'N';
if (CommonUtil.isNotEmpty(event)) {
// callback으로 전달 받은 데이터 매핑
if (CommonUtil.isNotEmpty(event.empNo)) {
angtEmpNo = event.empNo;
angtEmpNm = event.name;
angtDeptCd = event.deptCd;
angtGradCd = event.posiCd;
rprvApntYn = 'Y';
}
}
/** 출장자 Data */
const bztrpEmpData: Gaf0708D01Data = this.grdD0101Data;
/** 출장자 Data */
if (CommonUtil.isNotEmpty(bztrpEmpData)) {
if (CommonUtil.isNotEmpty(angtEmpNo)) {
// 내부인만 부재자 체크 진행
const param = {
empNo: angtEmpNo,
bginDt: this.saveParam.bztrpBginDt,
endDt: this.saveParam.bztrpEndDt,
};
// 부재자 체크하는 파라미터 VO확인하기@@@@
let abntAbleYn = '';
this.commonHttpService.get('/gaf/com/getabntableyn', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response: any) => {
// Y:부재자아님 N:부재자
abntAbleYn = response.body.abntAbleYn;
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
let refreshFlag = false;
if (bztrpEmpData.bztrpEmpNo === angtEmpNo) {
CommonUtil.commonMsg(
this.toastObj,
'해당 직원은 출장자에 포함되어 있습니다.',
'W'
);
refreshFlag = true;
} else if (
CommonUtil.isNotEmpty(abntAbleYn) &&
abntAbleYn === 'N'
) {
CommonUtil.commonMsg(
this.toastObj,
'해당 직원은 설정된 출장기간에 부재자로 등재되어 있습니다.',
'W'
);
refreshFlag = true;
}
// 데이터 매핑 결과가 없음 그대로 empty string으로 치환
// angtEmpNo 세팅
// const crudgrid: GridUpdateModel = {
// gridData: this.grdD0101Data,
// value: angtEmpNo,
// index: index,
// column: angtEmpNo
// };
this.grdD0101Data.angtEmpNo = angtEmpNo;
this.grdD0101Data.angtEmpNm = angtEmpNm;
// this.grdD0101Data[index].angtDeptCd = angtDeptCd;
this.grdD0101Data.angtGradCd = angtGradCd;
if (refreshFlag) {
this.grdD0101Data.angtEmpNo = '';
this.grdD0101Data.angtEmpNm = '';
this.grdD0101Data.angtGradCd = '';
//this.grdD0101?.refresh();
}
// this.commonGridService.gridCrudUpdate(crudgrid);
}
});
} else {
// 데이터 매핑 결과가 없음 그대로 empty string으로 치환
// const crudgrid: GridUpdateModel = {
// gridData: this.grdD0101Data,
// value: angtEmpNo,
// index: index,
// column: 'angtEmpNo'
// }
//update crud
// this.commonGridService.gridCrudUpdate(crudgrid);
// angtEmpNo 세팅
this.grdD0101Data.angtEmpNm = angtEmpNm;
this.grdD0101Data.angtGradCd = angtGradCd;
}
}
}
/*----------------- Data Handler End -----------------*/
/*----------------- Event Handler Start -----------------*/
// created(): void {
// this.calcGridHeight();
// // 새로고침 이슈 해결 법
// setTimeout(() => {
// this.calcGridHeight();
// }, CommonUtil.gridHeightDelay);
// }
// /**
// * grid 높이 계산
// *
// */
// calcGridHeight(): void {
// this.grdD0103Height = CommonUtil.commonGridHeight(0, 50);
// }
/**
* 권한 및 결재상태에 따른 버튼 제어
*
* @see setBtnHidden()
*/
changeBtnDisabled(): void {
this.adminChk = CommonUtil.hasRole('000000','R00201'); // 권한여부
if (GafUtil.getBooleanByApvStat(this.saveParam.misApprvStatCd)) {
this.btnRqstDisabled = true;
this.btnSaveDisabled = true;
this.btnDeleteDisabled = true;
this.grdItemEnabled = false;
this.bscGrdInptItemEnabled = false;
this.trfcCldvInptItemEnabled = false;
} else {
// 미저장/반려/저장 상태일 경우 수정/입력 가능
this.btnRqstDisabled = false;
this.btnSaveDisabled = false;
this.btnDeleteDisabled = false;
this.grdItemEnabled = true;
this.bscGrdInptItemEnabled = true;
this.trfcCldvInptItemEnabled = true;
}
if (CommonUtil.isEmpty(this.saveParam.misApprvStatCd)) {
this.btnDeleteDisabled = true;
}
/**
* @todo pgmId에 따른 분기 처리
*/
// 출장현황조회에서 창을 호출했을 때
if (this.pgmId === 'gaf1040') {
// CommonUtil.componentsEnable(false, idArr);
// CommonUtil.componentsVisible(false,btnArr);
// itemEnableYn = false;
// itemRenderEnabledTRP_COLS = false;
// btnC.visible = false;
this.btnRqstDisabled = true;
this.btnSaveDisabled = true;
this.btnDeleteDisabled = true;
this.grdItemEnabled = false;
this.bscInptItemEnabled = false;
this.bscGrdInptItemEnabled = false;
this.trfcCldvInptItemEnabled = false;
}
// 결재완료된 출장신청서 중 정산되지 않은 신청서는 출장 담당자 취소할 수 있음.
/**
* @todo 정산여부 칼럼 및 조건 추가해야 함.
* - FIX_YN === 'N'
*/
if (
this.adminChk &&
this.saveParam.misApprvStatCd === '31' &&
this.fixYn === 'N'
) {
this.btnCancelDisabled = false;
}
}
keydown(args: Event): void {
args.stopImmediatePropagation();
}
/**
* 행추가 시 필수값 체크
*
* @see requiredChk()
* @returns
*/
checkAddRow(): boolean {
if (CommonUtil.isEmpty(this.saveParam.bdgCd)) {
// 예산
this.commonMessageService.showMsg(
this.toastObj,
{message:message.com_warn_need_data.replace('{0}', '예산'),
type:'W'}
);
return false;
}
if (CommonUtil.isEmpty(this.saveParam.bztrpBginDt)) {
// 출장시작일자
this.commonMessageService.showMsg(
this.toastObj,
{message : message.com_warn_need_data.replace('{0}', '출장시작일자'),
type : 'W'}
);
return false;
}
if (CommonUtil.isEmpty(this.saveParam.bztrpEndDt)) {
// 출장종료일자
this.commonMessageService.showMsg(
this.toastObj,
{message : message.com_warn_need_data.replace('{0}', '출장종료일자'),
type : 'W'}
);
return false;
}
if (CommonUtil.isEmpty(this.saveParam.bztrpTotLodgNum)) {
// 박수
this.commonMessageService.showMsg(
this.toastObj,
{message : message.com_warn_need_data.replace('{0}', '박수'),
type : 'W'}
);
return false;
}
if (CommonUtil.isEmpty(this.saveParam.bztrpShpCd)) {
// 출장형태
this.commonMessageService.showMsg(
this.toastObj,
{message : message.com_warn_need_data.replace('{0}', '출장형태'),
type : 'W'}
);
return false;
}
return true;
}
recordDoubleClickGrdD0103(args: any): void {
if (this.saveParam.misApprvStatCd === '01') {
// 수정 가능일 경우만 수정 모드 활성화
this.commonGridService.gridCrudMode(this.grdD0103Data, args);
}
}
dataSourceChangeGrdD0103(args: any): void {
/* CommonUtil.commonGridScrollTop(this.grdD0103, args); // 조회 후 스크롤 상단으로 이동 */
}
grdD0103HeaderChkChange(args: any): void {
this.commonGridService.gridHeaderChkChange(this.grdD0103Data, args);
// CommonUtil.commonGridHeaderChkChange(this.grdD0103Data, args);
}
grdD0103ChkChange(args: any, index: number): void {
this.grdD0103Data[index].chk = args.checked;
this.headerChkGrdD0103 = this.commonGridService.gridDataChkChange(this.grdD0103Data);
// this.grdD0103Data[index].CHK = args.checked;
// this.headerChkGrdD0103 = CommonUtil.commonGridVirtualHeaderChk(
// this.grdD0103Data
// );
}
/**
* grdD0103 (출장내용) 행 추가
*
* @see addRow3()
*/
grdD0103AddRow(): void {
if (this.checkAddRow()) {
/** 삭제 대상이 아닌 실 출장내용 Array */
const existDataArray = this.grdD0103Data.filter((f: any) => f.crud !== 'D');
if (existDataArray.length > 4) {
this.commonMessageService.showMsg(this.toastObj, {message:'출장내용은 최대 5개로 제한해 주십시오.', type:'W'});
} else {
this.headerChkGrdD0103 = false;
let item : any = {};
// if (existDataArray.length === 0) {
// 첫행일 때
item = {bginDt : this.saveParam.bztrpBginDt, endDt : this.saveParam.bztrpEndDt}; // 1행 내용 입력 시 출장 시작일자로 일자 셋팀
// }
/*
else {
// 마지막 등록 데이터
const lastData = existDataArray[existDataArray.length - 1];
if (this.saveParam.bztrpBginDt === this.saveParam.bztrpEndDt) {
// 출장 시작일자와 종료일자가 같을 때 일자를 출장 시작일자로 셋팅
item = {dwupDt : this.saveParam.bztrpBginDt}; // 1행 내용 입력 시 출장 시작일자로 일자 셋팀
} else if (lastData.dwupDt === this.saveParam.bztrpEndDt) {
// 바로 전 행의 일자와 출장 종료일자가 같을 때 일자에 출장 종료일자 셋팅
item = {dwupDt : this.saveParam.bztrpEndDt};
} else if (
lastData.dwupDt !== this.saveParam.bztrpEndDt &&
this.saveParam.bztrpBginDt !== this.saveParam.bztrpEndDt
) {
// 바로 전 행의 일자가 출장 시작일자나 종료일자와 일치하지 않을 때 바로 전 행의 다음날짜를 일자에 셋팅
item = {dwupDt : this.commonDateService.getAddDate(1, lastData.dwupDt)};
}
}
*/
// 요일 계산
item['dy'] = GafUtil.getDayName(item.bginDt) + '~' + GafUtil.getDayName(item.endDt);
const obj: GridAddModel = {
gridObj : this.grdD0103
,gridData : this.grdD0103Data
, position: 'bottom'
, newData : item
}
this.commonGridService.gridAddRow(obj);
}
}
}
/**
* grdD0103 (출장내용) 행 삭제
*
* @see deleteRow3()
*/
grdD0103RemoveRow(): void {
this.headerChkGrdD0103 = false;
this.grdD0103?.clearSelection(); // 직접 구현한 체크박스 사용시 행삭제전 실행
const obj: GridDeleteModel = {
gridObj : this.grdD0103
,gridData : this.grdD0103Data
,toastObj: this.toastObj
,apiUrl: '/gaf/gaf0708/01/deleteCntn.do' // 저장 요청 url
,destroy : this.destroy
};
this.commonGridService.gridDeleteRow(obj);
}
/**
* grdD0103 엑셀 다운로드
*/
grdD0103ExcelExport(): void {
this.commonExcelService.gridSelectExcelExport(this.grdD0103, '출장내용');
}
/**
* grdD0102 엑셀 다운로드
*/
grdD0102ExcelExport(): void {
this.commonExcelService.gridSelectExcelExport(this.grdD0102, '출장지역');
}
/**
* 엑셀 다운로드 내용 포맷 설정
* @param $event
*/
excelQueryCellInfoHandler($event: any) {
const field = $event.column.field;
if (field === 'trfcAmt' || field === 'rmchrAmt'){
$event.value = this.comCommaPipe.transform($event.value);
} else if (field === 'dwupDt'){
$event.value = this.comDatePipe.transform($event.data.bginDt) + "~" + this.comDatePipe.transform($event.data.endDt);
} else if(field === 'drmtLodgYn') {
if(CommonUtil.isEmpty($event.value)) {
$event.value = 'N';
}
}else if(field === 'trfcDivCd') {
$event.value = 'NST';
}else if(field === 'dwntBztrp') { //시내출장 시간
$event.value = this.comDateTimePipe.transform($event.data.dwntBztrpBginHh) + "~" + this.comDateTimePipe.transform($event.data.dwntBztrpEndHh);
}else if(field === 'mvBginDt' || field === 'mvEndDt') { // 날짜
$event.value = this.comDatePipe.transform($event.value);
}
}
recordDoubleClickGrdD0101(args: any): void {
if(this.saveParam.misApprvStatCd === '01') {
// if(this.grdD0101Data.crud_mode) {
// this.grdD0101Data.crud_mode = false;
// }else {
this.grdD0101Data.crud_mode = true;
// }
//this.commonGridService.gridCrudMode(this.grdD0101Data, args);
}
}
grdD0101HeaderChkChange(args: any): void {
// CommonUtil.commonGridHeaderChkChange(this.grdD0101Data, args);
}
grdD0101ChkChange(args: any, index: number): void {
this.grdD0101Data.chk = args.checked;
/* this.headerChkGrdD0101 = CommonUtil.commonGridVirtualHeaderChk(
this.grdD0101Data
); */
}
recordDoubleClickGrdD0102(args: any): void {
if(this.saveParam.misApprvStatCd === '01') {
this.commonGridService.gridCrudMode(this.grdD0102Data, args);
}
}
/**
* 여행명세(경유지) 상세 다이얼로그 호출
*/
openGaf070815Dialog(item: Gaf0708D02Data, idx: number = -1): void {
if (this.checkAddRow()) {
/** 출장자 Data */
const btrpEmpData: Gaf0708D01Data = this.grdD0101Data;
//console.log('경유지', btrpEmpData);
if (CommonUtil.isEmpty(btrpEmpData?.bztrpEmpNo)) {
this.commonMessageService.showMsg(
this.toastObj,
{message:'여비산출내역에서 출장자를 먼저 선택하여 주십시오.',
type:'W'}
);
return;
}
this.headerChkGrdD0102 = false;
if (idx === -1) {
// 신규 등록일 때
item.bztrpEmpNo = btrpEmpData.bztrpEmpNo;
item.bztrpEmpNm = btrpEmpData.bztrpEmpNm;
item.bztrpGradCd = btrpEmpData.bztrpGradCd;
item.bztrpGradNm = btrpEmpData.bztrpGradNm;
// item.TRFC_AMT = 0;
item.chaeDivCd = 'A';
item.chaeDivNm = this.commonGridService.findLabel(
this.CHAE_DIV_CD_LIST,
'B'
); // 코드라벨 변경
// NST API 기본 선택
item.trfcDivCd = '807-008';
item.trfcDivNm = this.commonGridService.findLabel(
this.CHAE_DIV_CD_LIST,
item.trfcDivCd
); // 코드라벨 변경
// 여비등급코드
item.trexGrdCd = btrpEmpData.trexGrdCd;
// 신분등급코드
item.scpsGrdCd = btrpEmpData.scpsGrdCd;
}
const dialogConfig = new CommonMatDialogConfig();
dialogConfig.width = '800px';
dialogConfig.height = '500px';
dialogConfig.panelClass = ['modal-center'];
dialogConfig.data = {
rowData: item,
saveParam: this.saveParam,
idx: idx,
};
const dialogRef = this.dialog.open(Gaf070815Component, dialogConfig);
// 다이얼로그 데이터 저장
dialogRef.afterClosed().pipe(takeUntil(this.destroy))
// tslint:disable-next-line: deprecation
.subscribe((res: any) => {
console.log("dialog close", res);
if (CommonUtil.isNotEmpty(res)) {
res.trfcDivNm = this.commonGridService.findLabel(
this.TRFC_DIV_CD_LIST,
res.trfcDivCd
); // 코드라벨 변경
res.chaeDivNm = this.commonGridService.findLabel(
this.CHAE_DIV_CD_LIST,
res.chaeDivCd
); // 코드라벨 변경
// 숙박비 저장
this.lodgAmt = res.rmchrAmt;
this.dwntBztrpVisible = false;
// 시내출장일경우 (출발지=도착지)
if(res.arpnCd === res.stpnCd) { // 교육+시내출장은 한 건 이상 가능
res.dwntBztrpCd = '1'; // 시내출장
this.dwntBztrpVisible = true;
// 식비 없음
this.grdD0101Data.mealAmt = 0;
this.grdD0101Data.mealCnt = 0;
if(CommonUtil.isNotEmpty(this.grdD0102Data)) { // 이전 행이 존재 (이전행이 시내출장이 아니면 등록 할 수 없음.)
const cntList = this.grdD0102Data.filter((f:any) => f.dwntBztrpCd === '0' || f.stpnCd !== f.arpnCd);
if(cntList.length > 0) {
this.commonMessageService.showMsg(this.toastObj, { message: '시외출장과 시내출장은 함께 등록할 수 없습니다.', type: 'W'});
return;
}
if(this.saveParam.bztrpShpCd !== '5') {
this.commonMessageService.showMsg(this.toastObj, { message: '시내출장은 한 건만 등록할 수 있습니다.', type: 'W'});
return;
}
}
// 유연근무 시간 조회
this.fn_ftmInfo(this.grdD0102Data.length);
}else {
res.dwntBztrpCd = '0'; // 전일출장
// 시외출장을 등록하는데 시내출장 행이 이전에 등록되어있으면 x
const cntList = this.grdD0102Data.filter((f:any) => f.dwntBztrpCd === '1' || f.stpnCd === f.arpnCd);
if(cntList.length > 0) {
this.dwntBztrpVisible = true;
this.commonMessageService.showMsg(this.toastObj, { message: '시외출장과 시내출장은 함께 등록할 수 없습니다.', type: 'W'});
return;
}
}
res.nstLodgAmt = res.rmchrAmt; // nst 숙박비 값 저장
res.nstTrfcAmt = res.trfcAmt; // nst 교통비 값 저장
if(this.grdD0102Data.length === 0) { // 첫 경유지 등록시 출장 박수에 맞춰서 숙박일수 set + 출장일자로 set
res.rmchrAmt = this.saveParam.bztrpTotLodgNum * res.nstLodgAmt; // 숙박비
res.lodgDdNum = this.saveParam.bztrpTotLodgNum;
// 시작일자, 종료일자 => 출장일자로 기본 셋팅
res.mvBginDt = this.saveParam.bztrpBginDt;
res.mvEndDt = this.saveParam.bztrpEndDt;
// 첫 행 + 외부강의 일 때 체크박스 체크해주기
if(this.saveParam.bztrpShpCd == '5') {
res.extrlLctrYn = 'Y';
}
}else {
res.rmchrAmt = 0; // 숙박비
res.lodgDdNum = 0;
}
if (idx === -1) {
const obj: GridAddModel = {
gridObj: this.grdD0102,
gridData: this.grdD0102Data,
newData: res,
position: 'bottom'
}
this.commonGridService.gridAddRow(obj).gridCnt;
// 신규 행 추가일 경우
this.grdD0102AddRow(res);
} else {
// 행 수정일 경우
this.grdD0102UpdateRow(res, idx);
}
this.copyGrdD0102 = JSON.parse(JSON.stringify(this.grdD0102Data)); //그리드 복사
this.copyLodgD0102 = JSON.parse(JSON.stringify(this.grdD0102Data)); //숙박비그리드 복사
}
});
}
}
grdD0102HeaderChkChange(args: any): void {
this.commonGridService.gridHeaderChkChange(this.grdD0102Data, args);
}
grdD0102ChkChange(args: any, index: number): void {
this.grdD0102Data[index].chk = args.checked;
// this.headerChkGrdD0102 = CommonUtil.gridVirtualHeaderChk(
// this.grdD0102Data
// );
}
grdD0102Change2(args: any, index: number, column: string) {
if(args.event) {
this.grdD0102Data[index][column] = args.value;
const crudgrid: GridUpdateModel = {
gridData: this.grdD0102Data,
value: args,
index: index,
column: column
};
this.commonGridService.gridCrudUpdate(crudgrid);
}
}
// 경유지 그리드 수정
grdD0102Change(args: any, index: number, column: string) {
this.grdD0102Data[index][column] = args;
// 경유지 요금을 수정할 때 다시 계산 필요
if(column === 'trfcAmt') {
let trfcAmt : number = 0;
this.grdD0102Data.forEach((d) => {
trfcAmt += Number(d.trfcAmt);
});
// 출장자내역의 교통비에 적용
this.grdD0101Data.trfcAmt = trfcAmt;
if(args !== 0) {
this.copyGrdD0102[index].trfcAmt = args;
}
//this.calcTotAmt();
}else if(column === 'rmchrAmt'){ //숙박비 -> 수정 불가로 변경
let rmchrAmt : number = 0;
this.grdD0102Data.forEach((d) => {
rmchrAmt += Number(d.rmchrAmt);
});
// 출장자내역의 숙박비에 적용
this.grdD0101Data.lodgAmt = rmchrAmt;
}else if(column === 'dwntBztrpBginHh' || column === 'dwntBztrpEndHh') {
this.calAtplTrfcAmt(index); // 일비 계산
}else if(column === 'drmtLodgYn' || column === 'extrlLctrYn') { // 기숙사숙박여부 //외부강의여부
args = args.checked ? 'Y' : 'N';
this.grdD0102Data[index][column] = args;
if(column === 'extrlLctrYn' && CommonUtil.isNotEmpty(this.saveParam.bztrpRqstNo)) {
this.extrlLctrDisabled = args.checked ? true : false;
}
// if ('Y' === args) {
// this.grdD0102Data[index].drmtLodgYn = args;
// this.grdD0102Data[index].rmchrAmt = 0;
// }else {
// const rmchrAmt = this.copyLodgD0102[index].rmchrAmt; //숙박비 복사
// this.grdD0102Data[index].drmtLodgYn = args;
// this.grdD0102Data[index].rmchrAmt = rmchrAmt;
// if(this.saveParam.bztrp0AmtYn == 'Y' || this.grdD0102Data[index].extrlLctrYn == 'Y') { //0원출장 이거나 외부강의 일 때
// this.grdD0102Data[index].rmchrAmt = 0;
// }
// }
//this.copyGrdD0102 = JSON.parse(JSON.stringify(this.grdD0102Data));
}else if(column === 'lodgDdNum') { //숙박일수
// 기숙사 숙박, 외부강의가 아닐 때에만 계산
if(this.grdD0102Data[index].drmtLodgYn !== 'Y' && this.grdD0102Data[index].drmtLodgYn !== 'Y') {
const lodgDdNum = GafUtil.toInteger(args);
//const rmchrAmt = GafUtil.toInteger(this.copyLodgD0102[index].rmchrAmt) > 0 ? GafUtil.toInteger(this.copyLodgD0102[index].rmchrAmt) / GafUtil.toInteger(this.copyLodgD0102[index].lodgDdNum) : 0; //숙박비
const rmchrAmt = GafUtil.toInteger(this.grdD0102Data[index].nstLodgAmt ?? (this.copyLodgD0102[index].rmchrAmt > 0 ? GafUtil.toInteger(this.copyLodgD0102[index].rmchrAmt) / GafUtil.toInteger(this.copyLodgD0102[index].lodgDdNum) : 0)); //숙박비
const totLodg = lodgDdNum * rmchrAmt;
// 숙박일수 * 숙박비
this.grdD0102Data[index].rmchrAmt = totLodg;
}
}
// else if(column === 'extrlLctrYn') { //외부강의여부 -> 선택하면 모두 0원 처리
// args = args.checked ? 'Y' : 'N';
// this.grdD0102Data[index][column] = args;
// if(CommonUtil.isNotEmpty(this.saveParam.bztrpRqstNo)) {
// this.extrlLctrDisabled = args.checked ? true : false;
// }
// if ('Y' === args) {
// this.grdD0102Data[index].trfcAmt = 0;
// this.grdD0102Data[index].rmchrAmt = 0;
// this.grdD0101Data.atplTrfcAmt = 0;
// this.grdD0101Data.mealAmt = 0;
// this.grdD0101Data.mealCnt = 0;
// }else {
// this.grdD0102Data[index].trfcAmt = this.copyGrdD0102[index].trfcAmt;
// // 기숙사숙박여부 체크에 따른 값 설정
// if(this.grdD0102Data[index].drmtLodgYn === 'Y') {
// this.grdD0102Data[index].rmchrAmt = 0;
// }else {
// this.grdD0102Data[index].rmchrAmt = this.copyLodgD0102[index].rmchrAmt;
// }
// this.grdD0101Data.mealCnt = this.saveParam.bztrpTotDdNum*3;
// this.grdD0101Data.mealAmt = this.saveParam.bztrpTotDdNum*3*GafUtil.MEAL_PAY;
// this.calAtplTrfcAmtAll(); // 일비계산
// }
// }
if(column === 'drmtLodgYn') {
// 기숙사숙박여부 계산
this.fnCalDrmtLodgYn(index);
}
if(column === 'extrlLctrYn') {
// 외부강의여부 계산
//this.fnCalLctr(index);
if(CommonUtil.isNotEmpty(this.saveParam.bztrpRqstNo) && CommonUtil.isEmpty(this.grdD0102Data[index].sn) && this.grdD0102Data[index].extrlLctrYn === 'Y') {
this.fn_autoSaveForMv(index);
}
}
this.calcTotAmt();
const crudgrid: GridUpdateModel = {
gridData: this.grdD0102Data,
value: args,
index: index,
column: column
};
this.commonGridService.gridCrudUpdate(crudgrid);
}
/**
* grdD0102 행 추가
*
* @see addRow2()
*/
grdD0102AddRow(item: Gaf0708D02Data): void {
this.calcGrdD0102AmtChange();
}
/**
* grdD0102 행 수정
*
*/
grdD0102UpdateRow(item: Gaf0708D02Data, IDX: number): void {
}
/**
* grdD0102 행 삭제
*
* @see deleteRow2()
*/
grdD0102RemoveRow(): void {
this.headerChkGrdD0102 = false;
this.grdD0102?.clearSelection(); // 직접 구현한 체크박스 사용시 행삭제전 실행
const obj: GridDeleteModel = {
gridObj: this.grdD0102
, gridData :this.grdD0102Data
, toastObj : this.toastObj
, apiUrl: '/gaf/gaf0708/01/deleteMv.do' // 저장 요청 url
, destroy : this.destroy
, apiComplete: () => {
this.calAtplTrfcAmtAll(); //전체일비
this.calcGrdD0101TrfcAmt(); // 교통비
this.calcTotAmt(); // 출장비
// 외부강의 행삭제 일때 경유지 목록 기반으로 제외금액 구해야하기 때문에,
if(this.saveParam.bztrpShpCd === '5' && CommonUtil.isNotEmpty(this.saveParam.bztrpRqstNo)) {
this.fnGetMvList();
}
}
};
this.commonGridService.gridDeleteRow(obj).gridCnt;
// 복사
this.copyGrdD0102 = JSON.parse(JSON.stringify(this.grdD0102Data));
this.copyLodgD0102 = JSON.parse(JSON.stringify(this.grdD0102Data));
// 경유지 그리드 없으면 시내출장 초기화
if(this.grdD0102Data.length === 0) {
this.calDdMealAmt(); // 기본 식비 계산
this.dwntBztrpVisible = false;
}
this.calAtplTrfcAmtAll(); //일비
this.calcGrdD0101TrfcAmt(); // 교통비
this.calcTotAmt(); // 출장비
}
/**
* 비용 총합계 계산
* - (교통비 + 현지교통비 + 일비 + 숙박비 + 식비)
*
* @see doTotalAmtValue()
*/
calcTotAmt(flag:string = ''): void {
//console.log('calcTotAmt 비용 총합계 계산 >>>>',this.grdD0101Data);
if (CommonUtil.isEmpty(this.saveParam.trfcMensCd)) { //교통수단
this.saveParam.trfcMensCd = '0';
}
if (CommonUtil.isNotEmpty(this.grdD0101Data)) {
this.calcTrxpDdctAmt(flag); //공제금액계산
const btrpEmpData = this.grdD0101Data;
/** 총합계 */
let totAmt = 0;
/** 교통금액 traff_amt */
const trfcAmt = GafUtil.toInteger(btrpEmpData.trfcAmt);
/** 현지교통금액 cur_trf_exp */
const atplTrfcAmt = GafUtil.toInteger(btrpEmpData.atplTrfcAmt);
/** 숙박금액 lodg_exp */
const lodgAmt = GafUtil.toInteger(btrpEmpData.lodgAmt);
/** 식사금액 food_exp */
const mealAmt = GafUtil.toInteger(btrpEmpData.mealAmt);
/** 항공금액 air_exp */
//const airAmt = GafUtil.toInteger(btrpEmpData.airAmt);
/** 신청금액 aprq_amt */
// let rqstAmt = 0;
/** 개인지급금액 per_amt */
let persPrvdAmt = 0;
// 제외금액
const xcldCpdAmt = GafUtil.toInteger(btrpEmpData?.xcldCpdAmt??0);
const xcldTrfcAmt = GafUtil.toInteger(btrpEmpData?.xcldTrfcAmt??0);
const xcldChfdAmt = GafUtil.toInteger(btrpEmpData?.xcldChfdAmt??0);
totAmt = trfcAmt + atplTrfcAmt + lodgAmt + mealAmt + (xcldCpdAmt+xcldTrfcAmt+xcldChfdAmt); // 총합계
persPrvdAmt = trfcAmt + atplTrfcAmt + lodgAmt + mealAmt + (xcldCpdAmt+xcldTrfcAmt+xcldChfdAmt); // 개인지급액(교통비+현지교통비(0원)+일비 + 숙박비 + 식비)
btrpEmpData.totAmt = totAmt;
btrpEmpData.persProvdAmt = persPrvdAmt;
this.saveParam.rqstAmt = totAmt; // 총 출장비
this.saveParam.persProvdAmt = persPrvdAmt; // 총 개인지급액
//console.log("총 출장비", this.saveParam.rqstAmt);
}
}
/**
* 출장비 공제 금액 계산
* @see calcDeductionExp()
*/
calcTrxpDdctAmt(flag:string = ''): void {
// console.log('calcTrxpDdctAmt 출장비 공제 금액 계산');
/** 공제식사금액 */
let ddctMealAmt = 0;
/** 출장총숙박수 */
const bztrpTotLodgNum = CommonUtil.toInteger(this.saveParam.bztrpTotLodgNum);
/** 출장0금액여부 */
const btrp0AmtYn: string = this.saveParam.bztrp0AmtYn ?? 'N';
/** 출장자 Data */
const btrpEmpData = this.grdD0101Data;
// 식비공제가 있는지 확인한 후 ddctMealNum 횟수 저장
/** 방문기관식사포함수 */
const vsitInstMealInclNum: number = GafUtil.toInteger(this.saveParam.vsitInstMealInclNum);
/** 방문기관숙박포함수 */
const vsitInstLodgInclNum: number = this.saveParam.vsitInstLodgInclNum;
let extrlLectrCnt = 0;
// 외부강의 여부 확인
if(this.saveParam.bztrpShpCd === '5') {
this.grdD0102Data.forEach((d) => {
if(d.extrlLctrYn === 'Y') {
extrlLectrCnt++;
}
})
}
// 출장 식비 저장---------------------------------------------------------------------------------
if (CommonUtil.isNotEmpty(this.grdD0101Data) && btrp0AmtYn !== 'Y') {
// 식비공제 시작
// 20250305
// // 외부강의 일 때 0원 처리
// if(extrlLectrCnt === 1 && this.grdD0102Data.length === 1) {
// btrpEmpData.mealAmt = 0;
// btrpEmpData.mealCnt = 0;
// }else {
// if (vsitInstMealInclNum !== 0) { //공제항목이 있을 때
ddctMealAmt = this.saveParam.bztrpTotDdNum * 3 * GafUtil.MEAL_PAY - (vsitInstMealInclNum * GafUtil.MEAL_PAY);
/** 공제된 식비 */
const rsltDdctMealAmt: number = ddctMealAmt;
if(rsltDdctMealAmt == btrpEmpData.mealAmt) {
if (rsltDdctMealAmt < 0) {
// 식비가 0보다 작으면 0으로 계산
btrpEmpData.mealAmt = 0;
} else {
// 식비 공제
btrpEmpData.mealAmt = rsltDdctMealAmt;
}
}
if(CommonUtil.isNotEmpty(flag)) {
btrpEmpData.mealAmt = rsltDdctMealAmt;
btrpEmpData.mealCnt = this.saveParam.bztrpTotDdNum * 3 - vsitInstMealInclNum;
}
// 공제 횟수가 N식보다 많을 때 -> 걍 max로
if(vsitInstMealInclNum > this.saveParam.bztrpTotDdNum * 3) {
this.saveParam.vsitInstMealInclNum = this.saveParam.bztrpTotDdNum * 3;
btrpEmpData.mealAmt = 0;
btrpEmpData.mealCnt = 0;
this.commonMessageService.showMsg(this.toastObj, { message: "방문기관 제공 횟수는 최대 식사 횟수를 넘을 수 없습니다.", type: 'W'});
}
// }
// }
}
// 외부인&출장일수3일 이상일 경우 식비 직접 수정 처리때문에 추가 2022.07.11
if(btrpEmpData.imnYn !== 'Y' && this.totDay >= 3) {
btrpEmpData.mealAmt = this.mealAmt;
}
// 숙박일수 검증
if(bztrpTotLodgNum < vsitInstLodgInclNum) {
this.saveParam.vsitInstLodgInclNum = 0;
this.commonMessageService.showMsg(this.toastObj, { message: "방문기관 제공 횟수는 출장일수를 넘을 수 없습니다.", type: 'W'});
}
}
/**
* grdD0102의 출발지 도착지 Swap 처리
*
* @param number
* @see plcSwap(event:CommonEvent)
*/
grdD0102PnNmChange(index: number): void {
const d0102Data: Gaf0708D02Data = this.grdD0102Data[index];
const stpnNm = d0102Data.stpnNm;
const arpnNm = d0102Data.edpnNm;
d0102Data.stpnNm = arpnNm;
d0102Data.edpnNm = stpnNm;
}
/**
* 저장 전 체크
* @see doTrpRqstSaveChk()
*/
checkBeforeSave(): boolean {
let validate = false;
this.saveValid = 'Y';
validate = CommonUtil.frmValid(this.saveParam, this.toastObj, true);
if(!validate) {return validate;}
// 여행명세 경유지 체크
if (CommonUtil.isEmpty(this.grdD0102Data)) {
CommonUtil.commonMsg(this.toastObj, '출장지역이 없습니다.', 'W');
return false;
}else {
// 공제 내역 검증
const bztrpTotLodgNum = this.saveParam.bztrpTotLodgNum; //출장박수
const vsitInstLodgInclNum = this.saveParam.vsitInstLodgInclNum; //숙박비공제횟수
let lodgDdNum = 0;
this.grdD0102Data.forEach((d)=>{
lodgDdNum += GafUtil.toInteger(d.lodgDdNum);
})
if(bztrpTotLodgNum - vsitInstLodgInclNum < lodgDdNum) {
CommonUtil.commonMsg(this.toastObj, '출장지역의 숙박일수를 확인해주세요.', 'W');
return false;
}
this.grdD0102Data.forEach((d:any) => {
if(CommonUtil.isNotEmpty(d.mvBginDt)) {
if(!(this.saveParam.bztrpBginDt <= d.mvBginDt && d.mvBginDt <= this.saveParam.bztrpEndDt)) {
CommonUtil.commonMsg(this.toastObj, '출장지역의 일자가 출장정보의 출장기간을 벗어납니다.', 'W');
validate = false;
return;
}
}else {
CommonUtil.commonMsg(this.toastObj, '출장지역의 시작일자는 필수입니다.', 'W');
validate = false;
return;
}
if(CommonUtil.isNotEmpty(d.mvEndDt)) {
if(!(this.saveParam.bztrpBginDt <= d.mvEndDt && d.mvEndDt <= this.saveParam.bztrpEndDt)) {
CommonUtil.commonMsg(this.toastObj, '출장지역의 일자가 출장정보의 출장기간을 벗어납니다.', 'W');
validate = false;
return;
}
}else {
CommonUtil.commonMsg(this.toastObj, '출장지역의 종료일자는 필수입니다.', 'W');
validate = false;
return;
}
})
if(!validate) {return false;}
let cnt1 = 0;
let cnt2 = 0;
this.grdD0102Data.forEach((d:any) => {
// 첫째날과 마지막날이 있는지 확인
if(this.saveParam.bztrpBginDt === d.mvBginDt) {
cnt1++;
}
if(this.saveParam.bztrpEndDt === d.mvEndDt) {
cnt2++;
}
})
// 둘 중 하나라도 0이면 첫째날과 마지막날이 없는것
if(cnt1 === 0 || cnt2 === 0) {
CommonUtil.commonMsg(this.toastObj, '출장정보의 출장기간이 출장지역의 일자에 없습니다.', 'W');
validate = false;
return validate;
}
for(let i=0; i < this.grdD0102Data.length; i++) {
if(CommonUtil.isEmpty(this.grdD0102Data[i].bstaNm)) {
this.commonMessageService.showMsg(this.toastObj, { message: '목적지(기관)은 필수입니다.', type: 'W'});
return false;
}else {
if(CommonUtil.isEmpty(this.grdD0102Data[i].bztrpCntn)) {
this.commonMessageService.showMsg(this.toastObj, { message: '출장내역은 필수입니다.', type: 'W'});
return false;
}
}
}
// this.grdD0102Data.forEach((item:any) => {
// if(CommonUtil.isEmpty(item.bstaNm)) {
// this.commonMessageService.showMsg(this.toastObj, { message: '목적지(기관)은 필수입니다.', type: 'W'});
// validate = false;
// return;
// }else {
// if(CommonUtil.isEmpty(item.bztrpCntn)) {
// this.commonMessageService.showMsg(this.toastObj, { message: '출장내역은 필수입니다.', type: 'W'});
// validate = false;
// return;
// }
// }
// if(!validate) {return;}
// })
}
return validate;
// } else {
// CommonUtil.commonMsg(this.toastObj, CommonUtil.crudMsg01, 'W');
// Object.keys(this.form0101.controls).forEach((field) => {
// const control = this.form0101.get(field);
// control?.markAsDirty();
// control?.markAsTouched();
// });
// return false;
// }
// return true;
}
/*----------------- Event Handler End -----------------*/
/*----------------- Button Handler Start -----------------*/
/**
* 저장 버튼 클릭 이벤트 처리
* @see doTrpRqstSaveProcedure()
*/
btnSave(misApprvStatCd : string = ''): void {
// 출장기간은 필수, 빈값을 임시저장하면 다시 불러올 수 없다. 검색조건에 걸림.
if(CommonUtil.isEmpty(this.saveParam.bztrpBginDt) && CommonUtil.isEmpty(this.saveParam.bztrpEndDt)) {
this.commonMessageService.showMsg(this.toastObj, { message: '출장기간은 필수입니다.', type: 'W'});
return;
}
if('01'!==misApprvStatCd) { // 임시저장이 아닐 때만 검증
if (!this.checkBeforeSave()) { return; }
}
this.saveForm0101(misApprvStatCd);
}
/**
* 삭제 버튼 클릭 이벤트 처리
*/
btnDelete(): void {
this.deleteform0101('N');
}
/**
* 담당자 취소 버튼 클릭 이벤트 처리
*/
btnCrgrCncl(): void {
this.openCrgrCnclDialog();
}
/**
* 닫기 버튼 클릭 이벤트 처리
*/
btnClose(): void {
CommonUtil.windowClose();
}
/**
* 행추가 버튼 클릭 이벤트 처리
*/
btnGrdD0103AddRow(): void {
this.grdD0103AddRow();
}
/**
* 행삭제 버튼 클릭 이벤트 처리
*/
btnGrdD0103RemoveRow(): void {
this.grdD0103RemoveRow();
}
/**
* 엑셀 버튼 클릭 이벤트 처리
*/
btnGrdD0103Excel(): void {
this.grdD0103ExcelExport();
}
/**
* 엑셀 버튼 클릭 이벤트 처리
*/
btnGrdD0101Excel(): void {
// this.grdD0101
}
/**
* 행추가 버튼 클릭 이벤트 처리
*/
btnGrdD0102AddRow(): void {
let validate = true;
if(CommonUtil.isNotEmpty(this.grdD0102Data)) {
this.grdD0102Data.forEach((d) => {
if(d.stpnCd === d.arpnCd && this.saveParam.bztrpShpCd !== '5') { // 시내출장
this.commonMessageService.showMsg(this.toastObj, { message: '시내출장은 한 건만 등록할 수 있습니다.', type: 'W'});
validate = false;
}
});
}
if(validate) { this.openGaf070815Dialog(new Gaf0708D02Data()); }
}
/**
* 행삭제 버튼 클릭 이벤트 처리
*/
btnGrdD0102RemoveRow(): void {
this.grdD0102RemoveRow();
}
/**
* 엑셀 버튼 클릭 이벤트 처리
*/
btnGrdD0102Excel(): void {
this.grdD0102ExcelExport();
}
/**
* NST API 연동
* @param index
*/
btnNstApiTrfcAmt(index: number): void {
this.openNstApiTrfcAmt(index);
}
//메세지 토스트(알림)
toastEmit(args: any) {
this.toastObj = args;
}
// 다이얼로그 OPEN
fn_dialog(flag: any) {
const dialogConfig = new CommonMatDialogConfig();
dialogConfig.panelClass = ['modal-center'];
dialogConfig.data = { PGM_ID: 'gaf0708' };
if(flag === 'meal') {
dialogConfig.width = '500px';
dialogConfig.height = '450px';
this.dialog.open(Gaf0708mComponent, dialogConfig);
}else if(flag === 'daily') {
dialogConfig.width = '700px';
dialogConfig.height = '400px';
this.dialog.open(Gaf0708dpComponent, dialogConfig);
}else if(flag === 'xTrfc' || flag === 'xCpd' || flag === 'xChfd') {
dialogConfig.width = '520px';
dialogConfig.height = '230px';
dialogConfig.data = flag;
this.dialog.open(Gaf0708m2Component, dialogConfig);
}
}
// 시간계산, 교통수단 검색할때
fn_calTime() {
let time = 0;
const nLstt = '1200'; // 점심시작시간
const nLend = '1300'; // 점심종료시간
let choiceBginHh = '';
let choiceEndHh = '';
choiceBginHh = this.grdD0102Data[0].dwntBztrpBginHh;
choiceEndHh = this.grdD0102Data[0].dwntBztrpEndHh;
if(this.dwntBztrpVisible && CommonUtil.isNotEmpty(choiceBginHh) && CommonUtil.isNotEmpty(choiceEndHh)) {
let stTemp = '';
let edTemp = '';
if(choiceBginHh <= nLend && choiceEndHh >= nLstt) {
if(choiceEndHh >= nLend) {
stTemp = nLend;
}else {
stTemp = choiceEndHh;
}
if(choiceBginHh <= nLstt) {
edTemp = nLstt;
}else {
edTemp = choiceBginHh;
}
}else {
stTemp = '0';
edTemp = '0';
}
time = (Number(choiceEndHh) - Number(choiceBginHh)) - (Number(stTemp) - Number(edTemp))
time = time/100;
}
return time;
}
// 식비
fn_calMeal(flag:any) {
let mealAmt = 0;
let mealCnt = this.grdD0101Data.mealCnt;
if(flag === '+') {
mealAmt = this.grdD0101Data.mealAmt + GafUtil.MEAL_PAY;
mealCnt = mealCnt +1;
}else if(flag === '-') {
mealAmt = this.grdD0101Data.mealAmt - GafUtil.MEAL_PAY;
mealCnt = mealCnt -1;
}
if(mealAmt <= this.calMealMax().ddMaxAmt && mealCnt >= 0) {
this.grdD0101Data.mealCnt = mealCnt;
this.grdD0101Data.mealAmt = mealAmt;
}
}
//유연근무제 신청 정보
fn_ftmInfo(index:number) {
const param = {bztrpEmpNo: this.grdD0101Data.bztrpEmpNo , bztrpEndDt: this.saveParam.bztrpEndDt};
this.commonHttpService
.get('/gaf/gaf0708/getFtmInfo.do', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response : any) => {
if (CommonUtil.isNotEmpty(response)) {
//console.log(response.body);
const result = response.body;
if(CommonUtil.isNotEmpty(result)) {
this.grdD0102Data[index].dwntBztrpBginHh = result[0].choiceBginHh;
this.grdD0102Data[index].dwntBztrpEndHh = result[0].choiceEndHh;
this.saveParam.bginHh = result[0].choiceBginHh;
this.saveParam.endHh = result[0].choiceEndHh;
}else {
this.grdD0102Data[index].dwntBztrpBginHh = '0830';
this.grdD0102Data[index].dwntBztrpEndHh = '1730';
this.saveParam.bginHh = '0830';
this.saveParam.endHh = '1730';
}
}
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
this.calAtplTrfcAmtAll();
}
})
}
// 교통수단에 따른 계산
fnCalVecl() {
const veclYn = this.saveParam.trfcMensCd;
if(veclYn === '7') { //공용
// 교통비 0원
// 경유지 요금 0원
this.grdD0102Data.forEach((d)=>{
d.trfcAmt = 0;
})
//일비확인
this.calAtplTrfcAmtAll(); // 일비계산
}else { //일반
if(this.saveParam.bztrp0AmtYn == 'Y') {
this.grdD0102Data.forEach((d) => {
d.rmchrAmt = 0;
d.trfcAmt = 0;
d.atplTrfcAmt = 0;
})
}else {
//외부강의여부에 확인
for (let index = 0; index < this.grdD0102Data.length; index++) {
if(this.grdD0102Data[index].drmtLodgYn ==='Y'
// || this.grdD0102Data[index].extrlLctrYn ==='Y' //20250305
) {
this.grdD0102Data[index].rmchrAmt = 0;
this.grdD0102Data[index].lodgDdNum = 0;
}
// if(this.grdD0102Data[index].extrlLctrYn ==='Y') { //20250305
// this.grdD0102Data[index].trfcAmt = 0;
// }else {
this.grdD0102Data[index].trfcAmt = this.copyGrdD0102[index].trfcAmt;
// }
}
//일비확인
this.calAtplTrfcAmtAll(); // 일비계산
}
}
}
//기숙사숙박여부에 따른 계산
fnCalDrmtLodgYn(index:number) {
const drmtLodgYn = this.grdD0102Data[index].drmtLodgYn;
if(drmtLodgYn === 'Y') {
// 해당 로우의 숙박비를 0 처리
this.grdD0102Data[index].rmchrAmt = 0;
//this.grdD0102Data[index].lodgDdNum = 0;
}else {
//n일때
//0원 출장여부 확인
//외부강의여부 확인
//공용이면 요금 0원
if(this.saveParam.bztrp0AmtYn == 'Y') {
this.grdD0102Data[index].rmchrAmt = 0;
this.grdD0102Data[index].trfcAmt = 0;
//this.grdD0102Data[index].lodgDdNum = 0;
}else {
// if(this.grdD0102Data[index].extrlLctrYn === 'Y') { // 외부강의 여부 20250305
// this.grdD0102Data[index].rmchrAmt = 0;
// }else {
//this.grdD0102Data[index].lodgDdNum = this.grdD0102Data[index].lodgDdNum == 0 ? 1 : this.grdD0102Data[index].lodgDdNum;
//this.grdD0102Data[index].rmchrAmt = this.copyLodgD0102[index].rmchrAmt * this.grdD0102Data[index].lodgDdNum;
this.grdD0102Data[index].rmchrAmt =
GafUtil.toInteger(this.grdD0102Data[index].nstLodgAmt ?? (this.copyLodgD0102[index].rmchrAmt > 0 ? GafUtil.toInteger(this.copyLodgD0102[index].rmchrAmt) / GafUtil.toInteger(this.copyLodgD0102[index].lodgDdNum) : 0)) * GafUtil.toInteger(this.grdD0102Data[index].lodgDdNum);
// }
}
}
let rmchrAmt : number = 0;
this.grdD0102Data.forEach((d) => {
rmchrAmt += Number(d.rmchrAmt);
});
// 출장자내역의 숙박비에 적용
this.grdD0101Data.lodgAmt = rmchrAmt;
}
//외부강의여부에 따른 계산
fnCalLctr(index:number) {
const extrlLctrYn = this.grdD0102Data[index].extrlLctrYn;
// y면 모두 0원처리
if(extrlLctrYn === 'Y') {
this.grdD0102Data[index].trfcAmt = 0;
this.grdD0102Data[index].rmchrAmt = 0;
//this.grdD0102Data[index].lodgDdNum = 0;
if(this.grdD0102Data.length === 1) {
this.grdD0101Data.mealAmt = 0;
this.grdD0101Data.mealCnt = 0;
this.grdD0101Data.atplTrfcAmt = 0;
this.grdD0101Data.lodgAmt = 0;
}
}else {
//n일때
//교통수단 확인
//0원 출장여부 확인
if(this.saveParam.bztrp0AmtYn == 'Y') {
this.grdD0102Data[index].trfcAmt = 0;
this.grdD0102Data[index].rmchrAmt = 0;
//this.grdD0102Data[index].lodgDdNum = 0;
}else {
//기숙사숙박여부 확인
// 기숙사숙박여부 체크에 따른 값 설정
if(this.grdD0102Data[index].drmtLodgYn === 'Y') {
this.grdD0102Data[index].rmchrAmt = 0;
//this.grdD0102Data[index].lodgDdNum = 0;
}else {
//this.grdD0102Data[index].lodgDdNum = this.grdD0102Data[index].lodgDdNum == 0 ? 1 : this.grdD0102Data[index].lodgDdNum;
// this.grdD0102Data[index].rmchrAmt = this.copyLodgD0102[index].rmchrAmt * this.grdD0102Data[index].lodgDdNum;
this.grdD0102Data[index].rmchrAmt =
GafUtil.toInteger(this.grdD0102Data[index].nstLodgAmt ?? (this.copyLodgD0102[index].rmchrAmt > 0 ? GafUtil.toInteger(this.copyLodgD0102[index].rmchrAmt) / GafUtil.toInteger(this.copyLodgD0102[index].lodgDdNum) : 0))
* GafUtil.toInteger(this.grdD0102Data[index].lodgDdNum);
}
// 교통수단 확인
if(this.grdD0102Data[index].trfcMensCd === '7') {
this.grdD0102Data[index].trfcAmt = 0;
}else {
this.grdD0102Data[index].trfcAmt = this.copyGrdD0102[index].trfcAmt;
}
// 시내출장 아닐때
if(this.grdD0102Data[index].stpnCd !== this.grdD0102Data[index].arpnCd) {
// 식비
const vsitInstMealInclNum = this.saveParam.vsitInstMealInclNum ?? 0; //제공식사
this.grdD0101Data.mealCnt = this.saveParam.bztrpTotDdNum*3-vsitInstMealInclNum;
this.grdD0101Data.mealAmt = (this.grdD0101Data.mealCnt)*GafUtil.MEAL_PAY;
}
// 일비계산
this.calAtplTrfcAmtAll();
this.calcTotAmt();
}
}
}
calDdMealAmt() { // 하루 식비 계산
// 출장기간 확인
const ddNum = GafUtil.toInteger(this.saveParam.bztrpTotDdNum);
const ddCount = ddNum *3; // n식
const ddMaxAmt = ddCount * GafUtil.MEAL_PAY; // 일일 최대 금액
// 공제 확인
const vsitInstMealInclNum = GafUtil.toInteger(this.saveParam.vsitInstMealInclNum); // 방문기관 식사제공
const visitAmt = GafUtil.MEAL_PAY * vsitInstMealInclNum; // 공제 금액
if(CommonUtil.isNotEmpty(this.grdD0101Data)) {
this.grdD0101Data.mealCnt = ddCount - vsitInstMealInclNum;
this.grdD0101Data.mealAmt = ddMaxAmt - visitAmt;
}
}
calMealMax() {
const ddMaxNum = GafUtil.toInteger(this.saveParam.bztrpTotDdNum) * 3 - GafUtil.toInteger(this.saveParam.vsitInstMealInclNum);
const ddMaxAmt = GafUtil.MEAL_PAY * ddMaxNum;
return {'ddMaxNum':ddMaxNum, 'ddMaxAmt':ddMaxAmt};
}
createdD0102(): void {
this.grdD0102Height = 150;
}
// 배차신청 팝업 오픈
fn_veclRqst() {
const allocRqstNo = this.saveParam.allocRqstNo;
this.commonHttpService.get('/gaf/gaf0501/getChkAlloc.do',{}).pipe(takeUntil(this.destroy)).subscribe({
next: (response: any) => {
if(response.body.success) {
this.btnPopup(allocRqstNo);
}else{
this.commonMessageService.showSaveMsg(this.toastObj, response);
}
//this.fnGetGrdR01();
},
error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
},
complete: () => {
}
});
}
// 신규 팝업
btnPopup(allocRqstNo: string = '') {
this.saveParam.allocRqstNo = allocRqstNo;
const obj = { url : '/popup/gaf/gaf050101', width: 1400, height: 800, target: 'gaf050101', param: {allocRqstNo} };
const popup = CommonUtil.openWindowPopup(obj);
if (popup) {
this.unlistener = this.renderer2.listen(popup, 'message', (e) => {
if (e.origin === location.origin && CommonUtil.isNotEmpty(e.data.allocRqstNo)) { // 배차신청번호
// TODO 출장 테이블에 배차신청 pk update 해주기
const allocRqstNo = e.data.allocRqstNo;
this.saveParam.allocRqstNo = allocRqstNo;
this.fnAllocUpdate();
} else if(e.origin === location.origin && e.data === 'delete') {
this.commonMessageService.showMsg(this.toastObj, { message: message.com_succ_delete});
this.saveParam.allocRqstNo = '';
this.fnAllocUpdate();
}
});
}
}
/** 배차신청 pk 저장 */
fnAllocUpdate() {
this.commonHttpService.post('/gaf/gaf0708/01/updateAlloc.do', this.saveParam).pipe(takeUntil(this.destroy)).subscribe({
next: (response:any) => {
//this.commonMessageService.showSaveMsg(this.toastObj, response);
}
,error: (error: any) => {
this.commonMessageService.showSaveMsg(this.toastObj, error);
}
})
}
// 출장신청번호 존재, sn이 없고, 외부강의 y 일때 -> 저장
fn_autoSaveForMv(index:any) {
if(CommonUtil.isNotEmpty(this.saveParam.bztrpRqstNo) && CommonUtil.isEmpty(this.grdD0102Data[index].sn) &&
this.grdD0102Data[index].extrlLctrYn === 'Y') {
this.grdD0102Data[index].bztrpRqstNo = this.saveParam.bztrpRqstNo;
const param = this.grdD0102Data[index];
this.commonHttpService.post('/gaf/gaf0708/01/savemvlist.do', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response : any) => {
if(CommonUtil.isNotEmpty(response)) {
this.grdD0102Data[index].sn = response.body.results.sn;
}
},error: (error: any) => {
//this.commonMessageService.showSaveMsg(this.toastObj, error);
},complete: () => {
this.grdD0102Data[index].crud = 'U';
}
})
//todo 저장
}
}
// 일단 킵;;
// 이미 저장하여 nst 정보가 없을 때 (출장신청번호 존재, sn이 있을 때) -> 교통수단, 숙박비에 필요 (기숙사숙박여부, 숙박일수)
fn_getNstInfoForMv(index:any) {
if(CommonUtil.isNotEmpty(this.saveParam.bztrpRqstNo) && CommonUtil.isNotEmpty(this.grdD0102Data[index].sn)) {
// nst조회
const param = {
startCityCode : this.grdD0102Data[index].stpnCd,
endCityCode : this.grdD0102Data[index].arpnCd
}
let respObj: any;
this.commonHttpService.get('/gaf/com/getnstpath.do', param).pipe(takeUntil(this.destroy)).subscribe({
next: (response : any) => {
if(CommonUtil.isNotEmpty(response.body)) {
respObj = response.body;
} else {
this.commonMessageService.showSaveMsg(this.toastObj, response); // Exception 메시지 처리
}
},
error: () => {
this.commonMessageService.showMsg(
this.toastObj,
{message:'NST에서 해당 경로의 운임비를 조회하지 못 하였습니다. <br/> 직접 입력해주세요.',
type:'W'}
);
},
complete: () => {
if(this.grdD0102Data[index].chaeDivCd === 'A') { // 왕복
if(this.grdD0101Data.scpsGrdCd == '1' || this.grdD0101Data.scpsGrdCd == '0') { // 신분등급코드 책임급, 소장급
this.grdD0102Data[index].trfcAmt = respObj.sppayment*2; // 특실요금
}else {
this.grdD0102Data[index].trfcAmt = respObj.payment*2; // 요금
}
}else if(this.grdD0102Data[index].chaeDivCd === 'B'){ // 편도
if(this.grdD0101Data.scpsGrdCd == '1' || this.grdD0101Data.scpsGrdCd == '0') { // 신분등급코드 책임급, 소장급
this.grdD0102Data[index].trfcAmt = respObj.sppayment; // 특실요금
}else {
this.grdD0102Data[index].trfcAmt = respObj.payment; // 요금
}
}
//this.rowData.chaeDivCd = 'A'; // 요금구분
this.grdD0102Data[index].rmchrAmt = respObj.rmchrAmt; //숙박비
}
});
}
}
fnCalDate(index:any) {
const bgnDt = this.grdD0102Data[index]?.mvBginDt;
const endDt = this.grdD0102Data[index]?.mvEndDt;
if(CommonUtil.isEmpty(bgnDt) || CommonUtil.isEmpty(endDt)) {
CommonUtil.commonMsg(this.toastObj,
'시작일자 또는 종료일자를 입려해주세요.',
'W'
);
return;
}
const bgnDate: Date = new Date(CommonDate.getFormattedDate(bgnDt)); // 시작일 Date 객체
const endDate: Date = new Date(CommonDate.getFormattedDate(endDt)); // 종료일 Date 객체
const oneDay: number = 1000 * 60 * 60 * 24;
const bztrpTotDdNum: number = (endDate.getTime() - bgnDate.getTime() + oneDay) / oneDay;
this.totDay = bztrpTotDdNum; // 외부인&출장일수3일 이상일 경우 식비 직접 수정 처리때문에 추가 2022.07.11
const bztrpTotLodgNum: number = bztrpTotDdNum - 1;
return bztrpTotDdNum; //n일
}
/*----------------- Button Handler End -----------------*/
}
/**
* 기간 Validator
* @param control
* @returns
*/
export const bztrpDtRangeValidator: ValidatorFn = (
control: AbstractControl
): ValidationErrors | null => {
const bgnDt = control.get('bztrpBginDt');
const endDt = control.get('bztrpEndDt');
/* const bgnDate = new Date(this.commonDateService.getFormattedDate(bgnDt?.value)); // 시작일 Date 객체
const endDate = new Date(this.commonDateService.getFormattedDate(endDt?.value)); // 종료일 Date 객체 */
return null;
};