Browse Source

核子基因第一版

yuanzhi_kuang 5 months ago
commit
7382e720fc

+ 487 - 0
js/attendmanage/atsOverTimeBillBatchEditEx.js

@@ -0,0 +1,487 @@
+ /*
+ * 批量加班单拓展
+ * 202412
+ * 匡原志_coyle
+ */
+ 
+shr.defineClass(
+    "shr.ats.AtsOverTimeBillBatchEditEx", shr.ats.AtsOverTimeBillBatchEdit,
+    {
+        filter: {},
+        OTContrlParams: {},
+        initalizeDOM: function () {
+            shr.ats.AtsOverTimeBillBatchEdit.superClass.initalizeDOM.call(this);
+            var that = this;
+            that.remoteCall({
+                type: "post",
+                method: "getDecimalPlace",
+                //handler:
+                //    "com.kingdee.shr.ats.web.handler.AtsBillBaseEditHandler",
+                success: function (res) {
+                    fixedNum = res;
+                }
+            });
+
+            //		that.getOTContrlParams();
+            //按组织填充按钮
+            $(
+                '<button type="button" style="margin-left:4px;margin-right:4px" class="shrshrbtn-primary shrbtn" id="orgfill">' +
+                    jsBizMultLan.atsManager_atsOverTimeBillBatchEdit_i18n_17 +
+                    "</button>"
+            ).insertAfter($("#addRow_entries"));
+
+            var classfullNameService =
+                "com.kingdee.shr.ats.web.formEditImport.AtsOverTimeBillFileEditFormService";
+            //导入 按钮
+            $(
+                '<button type="button" style="margin-left:4px;margin-right:4px;display: none" class="shrshrbtn-primary shrbtn" id="import">' +
+                    jsBizMultLan.atsManager_atsOverTimeBillBatchEdit_i18n_3 +
+                    "</button>"
+            ).insertAfter($("#addRow_entries"));
+            $("#import").click(function () {
+                that.importAction(null, classfullNameService);
+            });
+
+            $(".editGrid-toolbar").append(
+                '<div style="display: inline;padding-left: 20px;">' +
+                    jsBizMultLan.atsManager_atsOverTimeBillBatchEdit_i18n_32 +
+                    '<div><div id="hasNum"></div>'
+            );
+            var serviceId = shr.getUrlRequestParam("serviceId");
+            var url =
+                shr.getContextPath() +
+                "/dynamic.do?checkLicense=true&uipk=com.kingdee.eas.hr.ats.app.OverTimeOrgFillForm";
+            url += "&serviceId=" + encodeURIComponent(serviceId);
+            $("#orgfill").click(function () {
+                $("#orgFillDiv").attr("src", url);
+                var gridNum = $("#entries").getGridParam("reccount");
+                $("#hasNum").val(gridNum);
+                $("#orgFillDiv").dialog({
+                    title:
+                        jsBizMultLan.atsManager_atsOverTimeBillBatchEdit_i18n_17,
+                    width: 1020,
+                    height: 450,
+                    modal: true,
+                    resizable: false,
+                    position: {
+                        my: "center",
+                        at: "top+20%",
+                        of: window
+                    },
+                    open: function (event, ui) {},
+                    buttons: [
+                        {
+                            text:
+                                jsBizMultLan.atsManager_atsOverTimeBillBatchEdit_i18n_19,
+                            click: function () {
+                                //校验F7数据
+                                if (that.checkF7Data()) {
+                                    var oldRowIds = $("#entries").getDataIDs();
+                                    that.fillGrid();
+                                    var newRowIds = $("#entries").getDataIDs();
+                                    rowIds = that.getFillRowId(
+                                        oldRowIds,
+                                        newRowIds
+                                    );
+                                    $.each(rowIds, function (n, value) {
+                                        //that.calRestTimeLen(value); 2015-11-03:组织填充不用自动计算时长
+                                        that.changOtTimeTipInfo(value);
+                                    });
+                                    //检查不超过100条记录
+                                    //that.checkRowIsOver();
+                                    $(this).dialog("close");
+                                } else {
+                                    return;
+                                }
+                            }
+                        },
+                        {
+                            text:
+                                jsBizMultLan.atsManager_atsOverTimeBillBatchEdit_i18n_5,
+                            click: function () {
+                                $(this).dialog("close");
+                            }
+                        }
+                    ]
+                });
+
+                $("#orgFillDiv").attr("style", "width:1020px;height:550px;");
+            });
+
+            var entries_cont = waf("#entries");
+            entries_cont.jqGrid("option", {
+                onChange: function (rowid, cellname, value, iRow, iCol) {
+                    console.log(rowid, cellname, value, iRow, iCol, 123123);
+                },
+                beforeSaveCell: function (
+                    rowid,
+                    cellname,
+                    value,
+                    iRow,
+                    iCol
+                ) {},
+                afterSaveCell: function (rowid, cellname, value, iRow, iCol) {
+                    if (value["adminOrgUnit.id"]) {
+                        $("#entries").jqGrid(
+                            "setCell",
+                            rowid,
+                            "adminOrgUnit.id",
+                            value["adminOrgUnit.id"]
+                        );
+                    }
+
+                    that.removePreShowError(rowid);
+                    if (cellname == "otDate") {
+                        var val = value;
+                        if (val.length <= 10) {
+                            val = val + " 00:00:00";
+                        }
+                        val &&
+                            $("#entries").jqGrid(
+                                "setCell",
+                                rowid,
+                                "startTime",
+                                val
+                            );
+                        val &&
+                            $("#entries").jqGrid(
+                                "setCell",
+                                rowid,
+                                "endTime",
+                                val
+                            );
+                        that.changeOverTimeType(rowid);
+                        that.calRestTimeLen(rowid);
+                        that.getOTContrlParams(rowid);
+                    }
+
+                    if (cellname == "otType") {
+                        that.changeOTCompens(rowid);
+                    }
+                    // 添加 开始时间  结束时间   休息时长(分钟) 响应时间
+                    if (
+                        cellname == "startTime" ||
+                        cellname == "endTime" ||
+                        cellname == "restTime"
+                    ) {
+                        if (cellname != "restTime") {
+                            that.calRestTimeLen(rowid);
+                        }
+                        that.calculateOTtimes(rowid);
+                    }
+                    if (cellname == "person") {
+                        that.calRestTimeLen(rowid);
+                        that.getOTContrlParams(rowid);
+                    }
+                    if (cellname == "applyOTTime") {
+                        // 加班小时数  发生改变就给予提示
+                        that.changOtTimeTipInfo(rowid);
+                    }
+                    if (
+                        cellname == "restStartTime" ||
+                        cellname == "restStartTime2" ||
+                        cellname == "restEndTime" ||
+                        cellname == "restEndTime2"
+                    ) {
+                        //计算休息时间,加班时间
+                        var startTime = $("#entries").jqGrid(
+                            "getCell",
+                            rowid,
+                            "startTime"
+                        );
+                        var endTime = $("#entries").jqGrid(
+                            "getCell",
+                            rowid,
+                            "endTime"
+                        );
+                        var restStartTime = $("#entries").jqGrid(
+                            "getCell",
+                            rowid,
+                            "restStartTime"
+                        );
+                        var restEndTime = $("#entries").jqGrid(
+                            "getCell",
+                            rowid,
+                            "restEndTime"
+                        );
+                        var restStartTime2 = $("#entries").jqGrid(
+                            "getCell",
+                            rowid,
+                            "restStartTime2"
+                        );
+                        var restEndTime2 = $("#entries").jqGrid(
+                            "getCell",
+                            rowid,
+                            "restEndTime2"
+                        );
+                        if (startTime == "" || endTime == "") {
+                            return;
+                        }
+                        
+                        var totalRestTime = 0;
+                        var totalRestTimeLong = 0;
+                        var restStartTimeOfDate;
+                        var restEndTimeOfDate;
+                        if(shr.getBowserInfo().browser === 'IE' || shr.getBowserInfo().browser === 'Safari'){
+                            restStartTime = restStartTime.replace(/-/g,'/');
+                            restEndTime = restEndTime.replace(/-/g,'/');
+                            restStartTime2 = restStartTime2.replace(/-/g,'/');
+                            restEndTime2 = restEndTime2.replace(/-/g,'/');
+                        }
+                        if (restStartTime != "" && restEndTime != "") {
+                            restStartTimeOfDate = new Date(restStartTime);
+                            restEndTimeOfDate = new Date(restEndTime);
+                            var times =
+                                restEndTimeOfDate.getTime() -
+                                restStartTimeOfDate.getTime();
+                            if (times < 0) {
+                                times = 0;
+                            }
+                            totalRestTimeLong += times;
+                            times = times / 1000 / 60;
+                            totalRestTime += times;
+                        }
+                        if (restStartTime2 != "" && restEndTime2 != "") {
+                            var restStartTime2OfDate = new Date(restStartTime2);
+                            var restEndTime2OfDate = new Date(restEndTime2);
+                            if (
+                                (restStartTime != "" &&
+                                    restEndTime2OfDate.getTime() >
+                                        restStartTimeOfDate.getTime() &&
+                                    restStartTimeOfDate.getTime() >=
+                                        restStartTime2OfDate.getTime()) ||
+                                (restEndTime != "" &&
+                                    restEndTimeOfDate.getTime() <=
+                                        restEndTime2OfDate.getTime() &&
+                                    restStartTime2OfDate.getTime() <
+                                        restEndTimeOfDate.getTime()) ||
+                                (restStartTime != "" &&
+                                    restEndTime != "" &&
+                                    restEndTimeOfDate.getTime() >=
+                                        restEndTime2OfDate.getTime() &&
+                                    restStartTime2OfDate.getTime() >=
+                                        restStartTimeOfDate.getTime())
+                            ) {
+                                //时间有交叉
+                                $("#entries").jqGrid(
+                                    "setCell",
+                                    rowid,
+                                    "restEndTime2",
+                                    restStartTime2
+                                );
+                            } else {
+                                var times =
+                                    restEndTime2OfDate.getTime() -
+                                    restStartTime2OfDate.getTime();
+                                if (times < 0) {
+                                    times = 0;
+                                }
+                                totalRestTimeLong += times;
+                                times = times / 1000 / 60;
+                                totalRestTime += times;
+                            }
+                        }
+                        var t1 = totalRestTime.toFixed(
+                            atsMlUtile.getSysDecimalPlace()
+                        );
+                        $("#entries").jqGrid("setCell", rowid, "restTime", t1);
+                        var startTime = NewDate(startTime + ":00");
+                        var endTime = NewDate(endTime + ":00");
+                        var se =
+                            endTime.getTime() -
+                            startTime.getTime() -
+                            totalRestTimeLong; // 毫秒
+                        // var tfl = se / (3600 * 1000);
+                        var tfl = Math.floor(se / (3600 * 1000));  // 向下取整
+                        $("#entries").jqGrid(
+                            "setCell",
+                            rowid,
+                            "applyOTTime",
+                            tfl
+                        );
+                        that.getOTContrlParams(rowid);
+                    }
+                },
+                afterEditCell: function (rowid, cellname, value, iRow, iCol) {
+                    if (
+                        cellname == "otType" &&
+                        that.OTContrlParams[rowid] &&
+                        that.OTContrlParams[rowid].isOtrolByDateType
+                    ) {
+                        $("#" + iRow + "_otType").shrPromptBox("disable");
+                    }
+                    if (cellname == "otCompens") {
+                        if (that.filter[rowid] == undefined) {
+                            // R20221006-0542 修复选择加班费后 再点击“补偿方式”F7就变成了调休的问题
+                            // that.changeOTCompens(rowid);
+                        }
+                        if (that.filter[rowid]) {
+                            //						$("#"+rowid+"_otCompens").shrPromptBox("setFilter",that.filter[rowid]);
+                            $(
+                                "#" +
+                                    $("#entries").jqGrid(
+                                        "getCell",
+                                        rowid,
+                                        "rn"
+                                    ) +
+                                    "_otCompens"
+                            ).shrPromptBox("setFilter", that.filter[rowid]);
+                        }
+                    }
+                    if (cellname == "person") {
+                        var hrOrgUnitId = $("#hrOrgUnit_el").val();
+                        $("#" + rowid + "_person")
+                            .shrPromptBox()
+                            .attr("data-params", hrOrgUnitId);
+                        $("#" + iRow + "_person").shrPromptBox("option", {
+                            onchange: function (e, value) {
+                                $("#entries").jqGrid(
+                                    "setCell",
+                                    rowid,
+                                    "person.number",
+                                    value.current
+                                        ? value.current["person.number"]
+                                        : ""
+                                );
+                            }
+                        });
+
+                    }
+                    if(cellname == "attAdminOrgUnit"){
+                        var personId = $("#entries").jqGrid("getCell", rowid, "person").id;
+                        var attendanceDate = $("#entries").jqGrid("getCell", rowid, "otDate");
+
+                        if(!(personId && attendanceDate)){
+                            shr.showInfo({message: jsBizMultLan.atsManager_atsOverTimeBillEdit_YM_999});
+                            return false;
+                        }else{
+                            //$("#"+rowid+"_attPosition").shrPromptBox().attr("data-params", adminOrg);
+                            $("#"+iRow+"_attAdminOrgUnit").shrPromptBox("setOtherParams", {
+                                personId: personId,
+                                attendanceDate: attendanceDate
+                            });
+                        }
+
+
+                    }
+
+
+                }
+            });
+
+            that.setButtonVisible(); //初始化页面安装状态,如果是已经提交的或者审批通过的单据编辑按钮不显示
+            //隐藏提交生效按钮
+            if (that.getOperateState() == "EDIT") {
+                if (that.isFromWF()) {
+                    // 来自流程中心
+                    $("#submitEffect").hide();
+                    $("#submit").text(
+                        jsBizMultLan.atsManager_atsOverTimeBillBatchEdit_i18n_25
+                    );
+                }
+            }
+
+            //审核编辑界面
+            if (
+                that.isFromWF() &&
+                that.getOperateState() == "EDIT" &&
+                $("#billState").val() != 0
+            ) {
+                $("#deleteRow_entries")
+                    .unbind("click")
+                    .attr("onclick", "")
+                    .css("cursor", "default");
+                $("#addRow_entries")
+                    .unbind("click")
+                    .attr("onclick", "")
+                    .css("cursor", "default");
+                $(".editGrid-toolbar").hide();
+                $("#submit").hide();
+
+                var lastRowNum = $("#entries").getGridParam("reccount");
+                for (var i = 1; i <= lastRowNum; i++) {
+                    var temp_id = $("#entries tr:eq(" + i + ")").attr("id");
+                    $("#entries").jqGrid(
+                        "setCell",
+                        temp_id,
+                        "person",
+                        "",
+                        "not-editable-cell"
+                    );
+                }
+            }
+
+            //考勤计算--已计算页签--明细显示模式--请假按钮进来,只显示提交生效按钮
+            if (
+                shr.getUrlParam("fromCalDetail") != null &&
+                shr.getUrlParam("fromCalDetail") == "1"
+            ) {
+                $("#save").hide();
+                $("#submit").hide();
+                $("#cancelAll").hide();
+                $("#import").hide();
+                $("#orgfill").hide();
+                $(".view_manager_header > div > div").eq(0).remove();
+                $("#submitEffect").addClass("shrbtn-primary");
+			$('#workAreaDiv .ui-jqgrid-bdiv').css('max-height','253px') // 当页面作为弹框时 表格过长则隐藏滑动
+            }
+            //增加业务组织处理
+            that.processF7ChangeEventHrOrgUnit();
+            var hrOrgUnitId = $("#hrOrgUnit_el").val();
+            that.initCurrentHrOrgUnit(hrOrgUnitId);
+            that.initCcPersonPrompt();
+        },
+
+
+        calculateOTtimes: function (rowid) {
+            var startTime = $("#entries").jqGrid("getCell", rowid, "startTime");
+            var endTime = $("#entries").jqGrid("getCell", rowid, "endTime");
+            var restTime = $("#entries").jqGrid("getCell", rowid, "restTime");
+
+            if (startTime == "[object Object]") {
+                $("#" + rowid)
+                    .find("td")
+                    .eq("5")
+                    .text("");
+                $("#" + rowid)
+                    .find("td")
+                    .eq("5")
+                    .attr("title", "");
+            }
+            if (endTime == "[object Object]") {
+                $("#" + rowid)
+                    .find("td")
+                    .eq("6")
+                    .text("");
+                $("#" + rowid)
+                    .find("td")
+                    .eq("6")
+                    .attr("title", "");
+            }
+
+            if (startTime != "" && endTime != "") {
+                var restVal = 0;
+                if (restTime != "" && /^[0-9]*$/.test(restTime)) {
+                    restVal = restTime; // 分钟数
+                }
+                var startTime = NewDate(startTime + ":00");
+                var endTime = NewDate(endTime + ":00");
+                var se =
+                    endTime.getTime() -
+                    startTime.getTime() -
+                    restVal * 1000 * 60; // 毫秒
+                // var tfl = se / (3600 * 1000);
+                var tfl = Math.floor(se / (3600 * 1000));  // 向下取整
+                $("#entries").jqGrid(
+                    "setCell",
+                    rowid,
+                    "applyOTTime",
+                    tfl.toFixed(fixedNum)
+                );
+            }
+        },
+         
+    }
+);
+
+ 

+ 87 - 0
js/attendmanage/atsOverTimeBillEditEx.js

@@ -0,0 +1,87 @@
+/**
+ * 加班单拓展
+ * 202412
+ * 匡原志_coyle
+ */
+shr.defineClass("shr.ats.AtsOverTimeBillEditEx", shr.ats.AtsOverTimeBillEdit, {
+    
+    initalizeDOM:function(){
+        shr.ats.AtsOverTimeBillEditEx.superClass.initalizeDOM.call(this);
+        var that = this ;
+         
+
+    },
+
+    calculataApplyOTTime : function(){
+        var startTime = atsMlUtile.getFieldOriginalValue("entries_startTime");
+        var endTime = atsMlUtile.getFieldOriginalValue("entries_endTime");
+        var restTime = atsMlUtile.getFieldOriginalValue("entries_restTime");
+        if( (new String(restTime)).trim()=='' ){
+            restTime=0;
+            atsMlUtile.setTransNumValue("entries_restTime",0,{'decimalPrecision':0});
+        }else{
+            restTime=parseFloat(restTime);
+            if(restTime<0.0){
+                atsMlUtile.setTransNumValue("entries_restTime",0,{'decimalPrecision':0});
+                restTime=0.0;
+            }
+        }
+
+        if ( startTime!=""&&startTime!=null && endTime!=""&&endTime!=null ) {
+
+            var regEx = new RegExp("\\-","gi");
+            startTime = startTime.replace(regEx,"/");
+            endTime = endTime.replace(regEx,"/");
+
+            var startTimeOfDate = new Date(startTime);
+            var endTimeOfDate = new Date(endTime);
+            var longTime = endTimeOfDate.getTime() - startTimeOfDate.getTime();
+            if (longTime <= 0) {
+                atsMlUtile.setTransNumValue("entries_applyOTTime",0);
+                //$("#entries_realOTTime").val(0);//时刻根据  实际的止-实际的起-休息通过在调用that.calculataApplyOTTime()后调用that.calculataRealOTTime()来达到的
+            }else{
+                t1 = parseFloat(longTime)/1000.0/60/60;
+                t1 = t1 - parseFloat(restTime)/60;
+                var that = this;
+                //向下取整
+                that.getDecimalPlace(Math.floor(t1),"entries_applyOTTime");
+            }
+        }
+    },
+
+
+    calculataRealOTTime : function(){
+        var realStartTime = atsMlUtile.getFieldOriginalValue("entries_realStartTime");
+        var realEndTime = atsMlUtile.getFieldOriginalValue("entries_realEndTime");
+        var restTime = atsMlUtile.getFieldOriginalValue("entries_restTime")||'';
+        if( (new String(restTime)).trim()=='' ){
+            restTime=0;
+            atsMlUtile.setTransNumValue("entries_restTime",0,{'decimalPrecision':0});
+        }else{
+            restTime=parseFloat(restTime);
+            if(restTime<0.0){
+                atsMlUtile.setTransNumValue("entries_restTime",0,{'decimalPrecision':0});
+                restTime=0.0;
+            }
+        }
+        if ( realStartTime!=""&&realStartTime!=null && realEndTime!=""&&realEndTime!=null ) {
+            var regEx = new RegExp("\\-","gi");
+            realStartTime = realStartTime.replace(regEx,"/");
+            realEndTime = realEndTime.replace(regEx,"/");
+            var realStartTimeOfDate = new Date(realStartTime);
+            var realEndTimeOfDate = new Date(realEndTime);
+            //lzq 加上减去休息时间
+            var floatTime = parseFloat( realEndTimeOfDate.getTime() - realStartTimeOfDate.getTime() )/1000.0/60/60 - parseFloat(restTime)/60;;
+            if (floatTime <= 0.0) {
+                atsMlUtile.setTransNumValue("entries_realOTTime",0);
+            }else{
+                //t1 = parseFloat(longTime)/1000.0/60/60;\
+                var that = this;
+                //向下取整
+                that.getDecimalPlace(Math.floor(floatTime),"entries_realOTTime");
+            }
+        }
+    },
+     
+
+});

+ 41 - 0
js/attendmanage/atsTripBillBatchNewEditEx.js

@@ -0,0 +1,41 @@
+/**
+ * 批量出差单
+ * coyle
+ * 202412
+ */
+
+ 
+shr.defineClass("shr.ats.atsTripBillBatchNewEditEx", shr.ats.atsTripBillBatchNewEdit, {
+
+    initalizeDOM: function () {
+        var _self = this;
+        shr.ats.atsTripBillBatchNewEditEx.superClass.initalizeDOM.call(this);
+       
+    },
+    
+
+     tripTimeChange: function (iRow, rowid, cellname) {
+        var _self = this;
+        _self.tripDaysLessThanActualValueStyleOff(iRow);
+        var cal_days = _self.calculataTripDays(rowid);
+        if (cal_days != null && cal_days >= 0) {
+            $("#entries").jqGrid("setCell", rowid, "tripDays", cal_days);
+            var trip_time = Math.ceil(cal_days * 7);
+            $("#entries").jqGrid("setCell", rowid, "triptime", trip_time);
+        }
+        var flag = false;
+        if (cellname == "tripStartTime") {
+            flag = true;
+        }
+        if (cellname == "startTimeDate" || cellname == "startTimeHMS") {
+            flag = true;
+        }
+
+        _self.calTripCrossTimeZone(rowid, flag, iRow);
+    }
+
+     
+
+
+});
+

+ 26 - 0
js/attendmanage/atsTripBillEditEx.js

@@ -0,0 +1,26 @@
+/**
+ * 出差单拓展
+ * coyle
+ * 202412
+ */
+shr.defineClass("shr.ats.AtsTripBillEditEx", shr.ats.AtsTripBillEdit, {
+    _uiClass: "",
+    initalizeDOM: function () {
+        shr.ats.AtsTripBillEditEx.superClass.initalizeDOM.call(this);
+        var that = this;
+        
+        $("#entries_tripDays").on("change", function () {
+            if (!$("#entries_tripEndTime").val()) {
+                that.getEndTime();
+            }
+            //计算总时间 定制 向上取整
+            var totalTime = $("#entries_tripDays").val() * 7 ;
+               $("#entries_triptime").shrTextField("setValue", Math.ceil(totalTime));
+        });
+
+         
+
+    },
+     
+
+});

+ 253 - 0
mbos/备份/我要出差_备份

@@ -0,0 +1,253 @@
+_this.pageinit = function () {
+    newPageInit()
+  }
+  // 从其他页面跳过来时,获取日期
+  function setDate() {
+    var date = moment(mbos.getRequestParams().date).format('YYYY-MM-DD')
+    if (date && mbos.getRequestParams().operateState == 'ADDNEW') {
+      mbos('entries_tripStartTime', 0).value(date + ' 08:00')
+      getStartEndTime(0)
+    }
+  }
+  
+  // 过滤出差类型F7 传递变量 ,dsQuery1为出差类型数据源的id
+  mbos('dsQuery1').bind('beforeLoad', function (e) {
+    var params = setParams('getTripTypeFilter', e.index) // 获取参数
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  
+  // 	在页面初始化加载之后
+  mbos('page').bind('afterLoad', function () {
+    _this.path = mbos.pageInfo.path// 轻应用的路径编码 例如 trip880
+    _this.detailPageCode = mbos.pageInfo.name.replace('Add', 'View') // 详情页面的编码 (个别页面可特殊处理直接写入) 例如 tripView.editui
+    _this.operateState = mbos.getRequestParams().operateState // 'ADDNEW' 'EDIT' 'VIEW'
+    // 初始化审批流
+    // mbos('nextperson1').checkParticipantPerson({
+    //   "callback": function () { }
+    // });
+    //   单据说明
+    mbos('description').bind('click', function () {
+      handleClickDesc()
+    })
+  })
+  mbos('entries').bind('afterRendered', function (e) {
+    showTimeZone(e.index)
+    multiLangField(e.index)// 兼容多语言字段回显的问题
+    if (e.index == 0) {
+      setDate()
+      // 初始化审批流
+        _this.getNextPerson();
+    }
+  })
+  // 初始化审批流
+  _this.getNextPerson = function(){
+    var entries = setModel('getNextPerson');
+    var data = JSON.parse(JSON.stringify(mbos('entity').value()));
+    data.entries = JSON.parse(JSON.stringify(entries));
+    var date = mbos.getRequestParams().date || new Date()
+    var today = moment(date).format('YYYY-MM-DD')
+    var beginTime = today + ' 00:00';
+    var endTime = today + ' 23:59';
+    mbos.eas.invokeScript({
+      name: "getHROrgUnit",
+      param: [{'beginTime': beginTime, 'endTime':endTime}],
+      success: function (res) {
+        console.log(res)
+        if(res.hrOrgUnitId){
+          data.hrOrgUnit = res.hrOrgUnitId
+        }
+        mbos('nextperson1').checkParticipantPerson({
+          'editdata': data,
+          "callback": function () { }
+        });
+      }
+    })
+  }
+  // 是否展示时区
+  function showTimeZone(index) {
+    var callback = function (res) {
+      if (res.data == 'true') {
+        mbos('entries_timeZone', index).show()
+      }
+    }
+    setModel()
+    baseInterface('isShowTimezone', callback, index)
+  }
+  // 保存按钮
+  _this.save = function (event) {
+    setModel()
+    baseInterface('save', toView) // 调用保存接口
+  }
+  // 提交按钮
+  _this.submit = function (event) {
+      // 确认提交 弹框
+    mbos.ui.showConfirm({
+      title: localeResource.confirmSubmit,
+      iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
+      callback: function (data) {
+        if (data == 0) {     
+          setModel()
+          baseInterface('submit', toView) // 调用提交接口
+        }
+      }
+    });
+  
+  }
+  
+  // 点击“保存、提交” 跳转页面
+  function toView(res) {
+    // 提交接口 返回的res.data为数组,取第一条数据
+    if (res.data.keyValue || (res.data.length > 0 && res.data[0].keyValue)) {
+      // 操作成功 提示弹框
+      mbos.ui.showInfo({
+        title: localeResource.succeed,
+        iconclass: "kdfont kdfont-zhuangtai_wancheng the_success",
+        callback: function () {
+          openPage(_this.path, _this.detailPageCode, { billID: res.data.keyValue || res.data[0].keyValue })
+        }
+      });
+    }
+  }
+  // 给隐藏的model赋值
+  function setModel(method) {
+    if (typeof _this.operateState != "undefined" && (_this.operateState === "ADDNEW" || _this.operateState === "EDIT")) {
+      var entries = mbos('entity').data.entries
+      entries.map(function (entry) {
+        entry.person = easContext.person
+        entry.position = easContext.position
+        entry.adminOrgUnit = easContext.position.adminOrgUnit
+        getEntries(entry,method) // 各单据处理分录数据
+      })
+      return entries
+    }
+  }
+  // 各单据处理分录数据的函数
+  function getEntries(entry,method) {
+    entry.startTimeHMS = entry.tripStartTime
+    entry.endTimeHMS = entry.tripEndTime
+    if(method == 'getNextPerson'){
+      // entry.position = easContext.position.id;
+      // entry.adminOrgUnit = easContext.position.adminOrgUnit.id;
+      if(entry.startTimeHMS){
+        entry.startTimeHMS = moment(entry.startTimeHMS).format('YYYY-MM-DD HH:mm:ss')
+      }
+      if(entry.tripStartTime){
+        entry.tripStartTime = moment(entry.tripStartTime).format('YYYY-MM-DD HH:mm:ss')
+      }
+      if(entry.endTimeHMS){
+        entry.endTimeHMS = moment(entry.endTimeHMS).format('YYYY-MM-DD HH:mm:ss')
+      }
+      if(entry.tripEndTime){
+        entry.tripEndTime = moment(entry.tripEndTime).format('YYYY-MM-DD HH:mm:ss')
+      }
+    }else{
+      // delete entry.position;
+      // delete entry.adminOrgUnit;
+      
+    }
+  }
+  // 计算单据时长
+  function getTimeLength(index) {
+    var callback = function (res) {
+      mbos('entries_tripDays', index).value(res.data)
+    }
+    setModel(index)
+    var entry = mbos('entity').data.entries[index]
+    if (entry.tripEndTime && entry.tripStartTime) {
+      baseInterface('getBillLength', callback, index)
+    }
+  }
+  // 根据时间判断 是否展示弹性算时长字段
+  function isElastic(index) {
+    var callback = function (res) {
+      if (res.data) {
+        mbos('entries_isElasticCalLen', index).show()
+      }
+    }
+    setModel(index)
+    var entry = mbos('entity').data.entries[index]
+    if (entry.tripEndTime && entry.tripStartTime) {
+      baseInterface('showIsElasticCalCtrl', callback, index)
+    }
+  }
+  // 获取整天的开始、结束时间
+  function getStartEndTime(i) {
+    var callback = function (res) {
+      mbos('entries_tripStartTime', i).value(moment(res.data.beginTime).format('YYYY-MM-DD HH:mm'))
+      mbos('entries_tripEndTime', i).value(moment(res.data.endTime).format('YYYY-MM-DD HH:mm'))
+      
+    }
+    if (mbos('entries_tripStartTime', i).value() || mbos('entries_tripEndTime', i).value()){
+      setModel(i)
+      var params = _.cloneDeep(mbos('entity').data)
+      var endTime = params.entries[i].tripEndTime
+      if (endTime && endTime.includes('00:00')) { // 防止结束日期会一直触发 
+        params.entries[i].tripEndTime = moment(endTime).subtract(1, "minutes").format("YYYY-MM-DD HH:mm")
+      }
+      // 【BT-01684276】改为传一条分录数据
+      params.entries = [params.entries[i]];
+      baseInterface('getAllDayBeginAndEndTime', callback, i, params)
+    }
+  }
+  
+  // 如果是整天出差 则使用date;否则使用datetime,同时清空时长
+  function recalcTime(event) {
+    mbos('entries_tripDays', event.index).value('')
+    if (String(event.new_value) == 'true') {
+      var entry = mbos('entity').data.entries[event.index]
+      if (entry.tripEndTime || entry.tripStartTime) {
+        getStartEndTime(event.index) // 获取pc端配置的起止时间
+        //  _this.startHadCalculate = true // 阻止二次触发 出差单整天时 开始时间触发问题
+        // _this.endHadCalculate = true // 阻止二次触发
+      }
+    }
+  }
+  
+  // 计算时长
+  _this.calTime1 = function (event) {
+    getTimeLength(event.index)
+    isElastic(event.index)
+    if (String(mbos('entries_isAllDay', event.index).value()) == 'true' && !Boolean(_this.startHadCalculate)) {
+      getStartEndTime(event.index)
+      // _this.startHadCalculate = true // 阻止二次触发
+    } else {
+      _this.startHadCalculate = false
+    }
+      console.log('startHadCalculate', _this.startHadCalculate)
+  }
+  _this.calTime2 = function (event) {
+    getTimeLength(event.index)
+    isElastic(event.index)
+    if (String(mbos('entries_isAllDay', event.index).value()) == 'true' && !Boolean(_this.endHadCalculate)) {
+      getStartEndTime(event.index)
+      // _this.endHadCalculate = true// 阻止二次触发
+    } else {
+      _this.endHadCalculate = false
+    }
+      console.log('endHadCalculate', _this.endHadCalculate)
+  }
+  // 监听是否整天
+  _this.calTime3 = function (event) {
+    getTimeLength(event.index)
+    recalcTime(event)
+  }
+  // 监听弹性
+  _this.calTime4 = function (event) {
+    getTimeLength(event.index)
+  }
+  
+  // 时长更改时 做校验
+  _this.lengthChange = function(event){
+    var value = event.new_value
+    //   判断是否小于0
+    if (!isNaN(parseFloat(value)) && value < 0) {
+      mbos.msgBox.showError(localeResource.lengthValid);
+      setTimeout(()=>{
+        mbos('entries_tripDays',event.index).value(0)
+      })
+      return
+    }
+    
+  }
+          
+  

+ 72 - 0
mbos/备份/我要出差_查看_备份

@@ -0,0 +1,72 @@
+// 	在页面初始化加载之后  
+mbos('page').bind('afterLoad', function () {
+    _this.operateState = mbos.getRequestParams().operateState // 页面状态
+    _this.path = mbos.pageInfo.path // 轻应用的路径编码
+    _this.editPageCode = mbos.pageInfo.name.replace('View', 'Add') // 详情页面的编码 (个别页面可特殊处理直接写入)
+    _this.title = localeResource.Travel_Request
+    toggleEntry() // 折叠\展开实体分录
+    toggleApprove() // 折叠\展开 审批流程
+    
+     _this.decimal = 4
+    getDecimal()// 获取pc配置的小数点数
+  })
+  mbos('entity').bind('afterLoad', function () {
+    initCommon(_this.title)// 初始化公共部分
+  })
+  
+  mbos('editgrid1').bind('afterRendered', function (e) {
+    activedEntry() // 保证蓝色的下标在对应分录上
+    var index = e.index
+    initPage() // 页面初始化时数据调整
+    timeStyle(e) // 起止时间的样式优化展示
+    // 是否展示弹性算时长字段
+    mbos('entries_isElasticCalLen', index).value() ? mbos('entries_isElasticCalLen', index).show(): mbos('entries_isElasticCalLen', index).hide()
+    $('#timeLength_' + index).find('label')[0].innerHTML = (mbos('timeLengthValue', index).value()).toFixed(_this.decimal) + localeResource.days;
+    $("[id^='entries_remark'] textarea").attr('rows', 3) // 多行文本 默认3行
+    $("[id^='entries_tripReason'] textarea").attr('rows', 3) // 多行文本 默认3行
+  })
+  // 获取pc配置的小数点数 默认为小数点后四位
+  function getDecimal(i){
+    var callback = function(res){
+      _this.decimal = res.data.decimalPlaceSystem || 4
+      
+    }
+    baseInterface('getDecimalPlace', callback) // 获取小数点数
+  }
+  // 编辑
+  _this.edit = function (event) {
+    editHandle(_this.path, _this.editPageCode)
+  }
+  // 删除
+  _this.delete = function (event) {
+    deleteHandle()
+  }
+  
+  // 撤回
+  _this.recall = function (event) {
+    // 未审批
+    recallHandle()
+  }
+  
+  // 提交
+  _this.toSubmit = function (event) {
+    submitHandle()
+  }
+  
+  // 分录中 时间的样式优化展示
+  function timeStyle(e) {
+    //   开始时间
+    var start = mbos('startTime', e.index).value().split(" ");
+    $('#sTime_' + e.index).find('label')[0].innerHTML = start[1];
+    $('#sDate_' + e.index).find('label')[0].innerHTML = start[0];
+    // 结束时间
+    var end = mbos('endTime', e.index).value().split(" ");
+    $('#eTime_' + e.index).find('label')[0].innerHTML = end[1];
+    $('#eDate_' + e.index).find('label')[0].innerHTML = end[0];
+    // 时长及箭头图标
+    $('#timeLength_' + e.index).find('label')[0].innerHTML = mbos('timeLengthValue', e.index).value() + localeResource.days;
+    $('#timeLength_' + e.index).find('label').addClass("lengthBottom");
+    $("#arrow_" + e.index).find('label').addClass("arrowIcon");
+  }
+          
+  

+ 455 - 0
mbos/备份/我要加班_备份

@@ -0,0 +1,455 @@
+_this.pageinit = function () {
+    var that = _this
+    _this.editInit = []
+    newPageInit(that)
+  }
+  
+  // 过滤考勤地点F7 传递变量 ,adminOrgQuery为数据源的id
+  mbos('adminOrgQuery').bind('beforeLoad', function (e) {
+    var params = setParams('getAtsAdminOrgUnitPlaceFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  // 过滤加班原因F7
+  mbos('AtsOTReasonAvailable').bind('beforeLoad', function (e) {
+    var params = setParams('getOverTimeReasonFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  // 过滤加班类型F7
+  mbos('AtsOTTypeAvailable').bind('beforeLoad', function (e) {
+    var params = setParams('getOverTimeTypeFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  // 过滤补偿方式F7
+  mbos('AtsOTCompensAvailable').bind('beforeLoad', function (e) {
+    var params = setParams('getOverTimeCompensFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  
+  // 	在页面初始化加载之后
+  mbos('page').bind('afterLoad', function () {
+    _this.path = mbos.pageInfo.path// 轻应用的路径编码 例如 trip880
+    _this.detailPageCode = mbos.pageInfo.name.replace('Add', 'View') // 详情页面的编码 (个别页面可特殊处理直接写入) 例如 tripView.editui
+    _this.operateState = mbos.getRequestParams().operateState // 'ADDNEW' 'EDIT' 'VIEW'
+    // 初始化审批流
+    mbos('nextperson1').checkParticipantPerson({
+      "callback": function () { }
+    });
+    //   单据说明
+    mbos('description').bind('click', function () {
+      handleClickDesc()
+    })
+    getDecimal()// 获取pc配置的小数点数
+  })
+  
+  mbos('entries').bind('afterRendered', function (e) {
+    _this.decimal = 4
+    getBillDetail(e.index) // 编辑页面渲染数据
+    getDateType(e.index)// 判断加班日期是单选还是多选还是日期区间
+    mbos('entries_applyOTTime', e.index).value() && (mbos('entries_applyOTTime', e.index).value()).toFixed(_this.decimal)
+    multiLangField(e.index)// 兼容多语言字段回显的问题
+  })
+  
+  
+  // 获取pc配置的小数点数 默认为小数点后两位
+  function getDecimal() {
+    var callback = function (res) {
+      _this.decimal = res.data.decimalPlaceSystem || 4
+    }
+    baseInterface('getDecimalPlace', callback) // 获取小数点数
+  }
+  // 判断加班日期是单选还是多选还是日期区间
+  function getDateType(i) {
+    var entry = mbos('entity').data.entries[i] // 当前明细数据
+    if (mbos('theOtDate', 0).$attrs.datemulti == 'true') {
+      _this.otDateType = 'dateMulti'
+      _this.isMulDays = true
+      mbos('entries.attAdminOrgUnit', i).hide() // 多日期隐藏考勤地点
+    } else if (mbos('theOtDate', 0).$attrs.datescope == 'true') {
+      _this.otDateType = 'dateScope'
+      _this.isMulDays = true
+      mbos('entries.attAdminOrgUnit', i).hide() // 多日期隐藏考勤地点
+    } else {
+      _this.otDateType = 'dateSingle'
+      _this.isMulDays = false
+      entry.isMulDays = false
+      mbos('theOtDateCoordinate', i).hide() // 单日期隐藏跨天
+      $('#theOtTime_' + i + ' .tooltip1').hide() // 单日期隐藏时间提示
+      mbos('theOtDateCoordinate', i).attr("mustinput", false) // 取消必填校验
+    }
+    if (mbos.getRequestParams().operateState === "ADDNEW") {
+      //   给【是否跨天】赋默认值【不跨天】
+      mbos('theOtDateCoordinate', i).value({ "value": "theDayNow", "alias": localeResource.just_today })
+    }
+  }
+  // 将时间格式化为时分
+  function getHMTime(time) {
+    return moment(time).format('HH:mm')
+  }
+  // 编辑页面渲染数据
+  function getBillDetail(i) {
+    var entry = mbos('entity').data.entries[i]
+    entry.otDate && mbos('theOtDate', i).value(moment(entry.otDate).format('YYYY-MM-DD'))
+    if (!_this.isMulDays) { getDateType(i) } // 未初始化时 _this.isMulDays可能为undefined
+    console.log(entry.startTime, i, entry.endTime, mbos('entity').data.entries)
+    if (_this.isMulDays) { // 多日期 时间的格式为时分
+      entry.endTime && mbos('theOtTime', i).value(getHMTime(entry.startTime) + '~' + getHMTime(entry.endTime))
+      entry.restStartTime && mbos('theRestInterval', i).value(getHMTime(entry.restStartTime) + '~' + getHMTime(entry.restEndTime))
+      entry.restStartTime2 && mbos('theRestInterval2', i).value(getHMTime(entry.restStartTime2) + '~' + getHMTime(entry.restEndTime2))
+    } else {
+      entry.restTime &&  mbos('restTime', i).value(entry.restTime)
+      entry.endTime && mbos('theOtTime', i).value(entry.startTime + '~' + entry.endTime)                        // 给加班时间赋值
+      entry.restStartTime && mbos('theRestInterval', i).value(entry.restStartTime + '~' + entry.restEndTime)      // 给休息时间赋值
+      entry.restStartTime2 && mbos('theRestInterval2', i).value(entry.restStartTime2 + '~' + entry.restEndTime2)  // 给休息时间2赋值
+    }
+  }
+  
+  
+  // 保存按钮
+  _this.save = function (event) {
+    setModel()
+    baseInterface('save', toView) // 调用保存接口
+  }
+  // 提交按钮
+  _this.submit = function (event) {
+      // 确认提交 弹框
+    mbos.ui.showConfirm({
+      title: localeResource.confirmSubmit,
+      iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
+      callback: function (data) {
+        if (data == 0) {
+          setModel()
+          baseInterface('submit', toView) // 调用提交接口
+        }
+      }
+    });
+    
+  }
+  
+  // 点击“保存、提交” 跳转页面
+  function toView(res) {
+    // 提交接口 返回的res.data为数组,取第一条数据
+    if (res.data.keyValue || (res.data.length > 0 && res.data[0].keyValue)) {
+          // 操作成功 提示弹框
+      mbos.ui.showInfo({
+        title: localeResource.succeed,
+        iconclass: "kdfont kdfont-zhuangtai_wancheng the_success",
+        callback: function () {
+          openPage(_this.path, _this.detailPageCode, { billID: res.data.keyValue || res.data[0].keyValue })
+        }
+      });
+      
+    }
+  }
+  // 给隐藏的model赋值
+  function setModel() {
+    if (typeof _this.operateState != "undefined" && (_this.operateState === "ADDNEW" || _this.operateState === "EDIT")) {
+      var entries = mbos('entity').data.entries
+      entries.map(function (entry, index) {
+        entry.person = easContext.person
+        entry.position = easContext.position.id
+        entry.adminOrgUnit = easContext.position.adminOrgUnit.id
+        getEntries(entry, index) // 各单据处理分录数据
+      })
+    }
+  }
+  
+  
+  
+  // 各单据处理分录数据的函数
+  function getEntries(entry, i) {
+    //   跨天方式
+    if (mbos('theOtDateCoordinate', i).value()) {
+      entry.theOtDateCoordinate = mbos('theOtDateCoordinate', i).value().value
+    }
+    entry.isMulDays = _this.isMulDays
+    entry.otDate = _this.isMulDays ? entry.dynamic_Field1 && entry.dynamic_Field1.split(',')[0] : entry.otDate || entry.theOtDate || mbos('theOtDate', i).value() // 加班日期
+    // 【BT-01701321】【V9.0第一轮集成测试】移动端撤回加班单后修改休息时间再提交,休息时间和加班小时数不正确。修改为休息时长60min后,再修改为休息时间0,提交后休息时间还是60
+    if(entry.restTime === undefined){
+      entry.restTime = ''
+    }
+  } 
+  // 单日期 获取默认加班类型和补偿方式
+  function getOverTimeTypeAndOtCompens(index) {
+    var callback = function (res) {
+      if (res.data) {
+        if (res.data.otTypeValue && res.data.otTypeText){
+          mbos('entries_otType', index).value({ id: res.data.otTypeValue, name: res.data.otTypeText })
+        } else {
+           mbos.ui.showError(localeResource.checkShift)
+        }
+        res.data.compensInfo && mbos('entries_otCompens', index).value(res.data.compensInfo)
+      }
+    }
+    setModel()
+    baseInterface('getOverTimeTypeAndOtCompens', callback, index)
+  }
+  // 单日期 获取加班班次
+  function getMyScheduleTime(index) {
+    var callback = function (res) {
+  //     默认班次存在则显示 不存在则隐藏
+      if (res.data && res.data.defaultShift && res.data.defaultShift.name) {
+        document.getElementById('attendanceShift_' + index).innerText = `${res.data.defaultShift.name}`
+        $('#attendanceShift_' + index).css('display', 'flex')
+      } else {
+        document.getElementById('attendanceShift_' + index).innerText = ''
+        $('#attendanceShift_' + index).css('display', 'none')
+      }
+    }
+    setModel()
+    baseInterface('getMyScheduleTime', callback, index)
+  }
+  // 根据起始时间计算休息分钟数
+  function getDiffMinites(sTime, eTime, hour) {
+    if (sTime && eTime) {
+      // 通过正则将'-'改为'/'(ios系统不认得'-'却认得'/')
+      var date1 = new Date(sTime.replace(/-/g, '/')).getTime()
+      var date2 = new Date(eTime.replace(/-/g, '/')).getTime()
+      if (sTime.split(' ')[1] && date1 > date2) { // 单日期 计算时间才需要判断
+        mbos.ui.showError(hour ? localeResource.ot_tips : localeResource.rest_tips)
+        return 
+      }
+      return hour ? Math.abs((date2 - date1) / 1000 / 60 / 60) : Math.abs((date2 - date1) / 1000 / 60)
+    }
+  }
+  // 获取默认休息时间
+  function getDefaultRestTime(index) {
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    var callback = function (res) {
+      if (res.data) {      //         如果无值则渲染 有值则不予更改,用户手动填写的数据优先级最高
+        if (!mbos('theRestInterval', index).value()) {
+          if (res.data.restEndTime) {
+            entry.restTime = res.data.restTime
+            mbos('theRestInterval', index).value(res.data.restStartTime + '~' + res.data.restEndTime)
+          } else {
+            // mbos('theRestInterval', index).value('')
+            entry.restStartTime = ''
+            entry.restEndTime = ''
+          }
+        }
+        //     休息时间2    如果无值则渲染 有值则不予更改,用户手动填写的数据优先级最高
+        if (!mbos('theRestInterval2', index).value()) {
+          if (res.data.restEndTime2) {
+            entry.restTime = res.data.restTime
+            !mbos('theRestInterval2', index).value() && mbos('theRestInterval2', index).value(res.data.restStartTime2 + '~' + res.data.restEndTime2)
+          } else {
+            // mbos('theRestInterval2', index).value('')
+            entry.restStartTime2 = ''
+            entry.restEndTime2 = ''
+          }
+        }
+        // entry.applyOTTime = ((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0).toFixed(_this.decimal) // 加班时长
+        //  202412  加班时长改为小时数向下取整
+        entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0) ;
+
+      }
+    }
+    if (_this.otDateType == 'dateSingle' && entry.theOtDate) {
+      setModel()
+      baseInterface('getMyRestTime', callback, index)
+    }
+  }
+  // 单日期时判断”加班类型“是否是被禁用
+  function isDisabledDateType(otDate, index) {
+    var callback = function (res) {
+      if (res.data.otrolByDateType) {
+        mbos('entries_otType', index).disable() // 如果返回为true 则禁用
+      } else {
+        mbos('entries_otType', index).attr('disabled', false)
+      }
+    }
+    if (otDate) {
+      setModel()
+      baseInterface('getAttencePolicyInfo', callback, index)
+    }
+  }
+  /**
+   * @description: 根据开始日期结束日期的时区,获取逗号拼接的日期字符串
+   * @return {String}
+   */
+  function getDates(sDate, eDate) {
+    var list = [sDate]
+    var value = sDate
+    while (value < eDate) {
+      value = moment(value).add(1, 'days').format('YYYY-MM-DD')
+      list.push(value)
+    }
+    return list.join(',')
+  }
+  // 非单日期 日期change事件
+  function multiDateChange(dateString, entry, index) {
+    entry.isMulDays = true
+    entry.otDates = dateString
+    entry.theOtDateCoordinate = 'theDayNow'
+    entry.days = dateString.split(',').length // 天数
+    entry.restTime = (getDiffMinites(entry.restStartTime, entry.restEndTime) + getDiffMinites(entry.restStartTime2, entry.restEndTime2)) * entry.days || 0
+    // entry.applyOTTime = ((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0).toFixed(_this.decimal)
+    // 202412  加班时长改为小时数向下取整
+    entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0); 
+    // 校验多选日期是否是同一时间类型 如果不是则清空
+    var callback = function (res) {
+      if (res.data && !res.data.isSameDay) {
+        mbos.ui.showError({
+          title:  localeResource.tips,
+          detail: localeResource.diff_type_tips,
+          iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
+          callback: function (data) {
+            mbos('theOtDate', index).value(''); // 先清空
+            mbos('theOtDate', index).open(); // 再自动打开弹框
+          }
+        });
+      }
+    }
+    if (entry.days > 1) {
+      setModel()
+      baseInterface('getDateTypeIsSame', callback, index) // 校验多选日期是否是同一时间类型
+    }
+    // mbos('theOtTime', index).timeFormat("HH:mm")
+  }
+  /**
+   * @description: 监听加班日期;
+   * 单日期则改变 加班开始/结束时间、加班时间;
+                休息开始/结束时间、休息时间;
+                休息时长、加班时长
+                加班类型\加班补偿方式\加班日期班次
+    * 
+    * 多选日期/时间区间 则改变:休息时长、加班时长
+    * 
+    1、pc端配置的默认加班时间;
+    2、默认休息时间;
+    3、加班类型、补偿方式接口;
+    4、带出对应班次;
+  【以上接口仅单日期触发】 【EDIT页面初始化时,不调以上4个接口】
+    * @return {*}
+    */
+  _this.otDateChange = function (event) {
+    var index = event.index
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    var theOtDate = event.new_value // 加班日期
+    if (!_this.otDateType) {
+      getDateType(index)
+    }
+    if (!theOtDate) {
+      mbos('theOtTime', index).value('')
+      return
+    }
+    var otDateType = _this.otDateType // 日期类型
+    if (otDateType == 'dateScope') { // 日期区间
+      if (theOtDate) {
+        var sDate = moment(theOtDate.split('~')[0]).format('YYYY-MM-DD')
+        var eDate = theOtDate.split('~')[1] ? theOtDate.split('~')[1] : sDate
+        theOtDate = getDates(sDate, eDate)
+        multiDateChange(theOtDate, entry, index)
+      }
+    } else if (otDateType == 'dateMulti') { // 多选日期
+      multiDateChange(theOtDate, entry, index)
+    } else if (otDateType == 'dateSingle') { // 单选日期
+      if (event.new_value && event.old_value && moment(event.new_value).format('YYYY-MM-DD') === moment(event.old_value).format('YYYY-MM-DD')) return
+      theOtDate = moment(theOtDate).format('YYYY-MM-DD')
+      entry.otDate = theOtDate
+      entry.theOtDate = theOtDate
+      entry.isMulDays = false
+      getMyScheduleTime(index) // 加班班次
+      isDisabledDateType(theOtDate, index)  // 待更新到外网
+      entry.days = 1
+      if (!entry.startTime && !entry.endTime) {
+        // 加班时间【00:00】 二开用户可自定义
+        mbos('theOtTime', index).value(theOtDate + ' 00:00~' + theOtDate + ' 00:00') // 给加班时间赋默认值
+      } 
+      getOverTimeTypeAndOtCompens(index) // 加班类型&补偿类型
+      getDefaultRestTime(index) // 获取默认休息时间
+    }
+  }
+  /**
+   * @description: 监听加班时间:默认休息时间(调接口)
+   * @event: applyOTTime = otIntervalLength - restTime => 加班时长 = 跨度时长 - 休息时长
+   * @return {*}
+   */
+  _this.otTimeChange = function (event) {
+    var index = event.index
+    var theOtTime = event.new_value // 加班时间
+    var startTime = theOtTime.split('~')[0]
+    var endTime = theOtTime.split('~')[1]
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    _this.anyDate = entry.otDates && entry.otDates.split(',')[0] || '2020-01-01' // 仅作拼接使用 无任何意义
+    if (!theOtTime) {
+      entry.applyOTTime = 0
+    }
+    startTime = _this.isMulDays ? _this.anyDate + ' ' + startTime : startTime // 确保 格式为年月日时分
+    endTime = _this.isMulDays ? _this.anyDate + ' ' + endTime : endTime // 确保 格式为年月日时分   同一天
+    if (startTime > endTime) { // 跨天
+      var tomorrow = moment(_this.anyDate).add(1, 'days').format('YYYY-MM-DD')
+      endTime = _this.isMulDays ? tomorrow + ' ' + endTime : endTime  // 确保 格式为年月日时分
+    }
+  
+    entry.startTime = startTime // 赋值加班开始时间
+    entry.endTime = endTime // 赋值加班结束时间
+    entry.otIntervalLength = getDiffMinites(startTime, endTime, 'hour') // 加班的一天跨度时长
+  
+    if (!entry.days) entry.days = 1
+    // entry.applyOTTime = ((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0).toFixed(_this.decimal) // 加班时长
+    //202412改 向下取整
+    entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0) ; // 加班时长
+  
+    if (mbos.getRequestParams().operateState !== 'EDIT' || _this.init) {
+      getDefaultRestTime(index) // 更新休息时间
+    } else {
+      _this.init = true
+    }
+  }
+  /**
+   * @description: 监听【休息时间1】改变时长
+   * @event: 
+   * @return {*}
+   */
+  _this.restTimeChange = function (event) {
+    restChange(event, "restStartTime", "restEndTime", "restTime1")
+  }
+  
+  // 监听【休息时间2】改变时长
+  _this.restTimeChange2 = function (event) {
+    restChange(event, "restStartTime2", "restEndTime2", "restTime2")
+  }
+  // 休息时间控件监听 start, end, time分别为对应的字段名
+  function restChange(event, start, end, time) {
+    var index = event.index
+    //   如果两个休息时间都为空,则时间长度可编辑;否则不可编辑
+    if (!mbos('theRestInterval', index).value() && !mbos('theRestInterval2', index).value()) {
+      mbos('entries_restTime', index).enable()
+    } else {
+      mbos('entries_restTime', index).disable()
+    }
+  
+    _this.anyDate = '2020-01-01' // 仅作拼接使用 无任何意义
+  
+    var theRestInterval = event.new_value // 休息时间
+    var startTime = theRestInterval.split('~')[0]
+    var endTime = theRestInterval.split('~')[1]
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+  
+    var notToday = startTime > endTime  // 如果开始时间大于结束时间则表示跨天了
+    entry[start] = _this.isMulDays ? _this.anyDate + ' ' + startTime : startTime // 确保 格式为年月日时分
+    var tomorrow = moment(_this.anyDate).add(1, 'days').format('YYYY-MM-DD')
+    entry[end] = _this.isMulDays ? (notToday ? tomorrow + ' ' + endTime : _this.anyDate + ' ' + endTime) : endTime // 确保 格式为年月日时分
+    entry[time] = theRestInterval ? getDiffMinites(entry[start], entry[end]) * (entry.days || 1) : 0
+    if (entry.restTime1 == 0 && entry.restTime2 == 0) {
+      entry.restTime = entry.restTime || 0
+    } else {
+      entry.restTime = (entry.restTime1 || 0) + (entry.restTime2 || 0)
+    }
+    
+    // entry.applyOTTime = ((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0).toFixed(_this.decimal) // 加班时长
+    // 202412改 向下取整
+    entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0) ; // 加班时长
+  
+  }
+  // 休息时长改动
+  _this.restLengthChange = function (event) {
+    var index = event.index
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    if (mbos('entries_applyOTTime', index).value()) {
+      // entry.applyOTTime = (entry.otIntervalLength * entry.days - (event.new_value || 0) / 60 || 0).toFixed(_this.decimal)
+      // 202412改 向下取整
+      entry.applyOTTime = Math.floor( (entry.otIntervalLength * entry.days - (event.new_value || 0) / 60 || 0) );
+    }
+  }
+      

+ 283 - 0
mbos/我要出差.js

@@ -0,0 +1,283 @@
+_this.pageinit = function () {
+    newPageInit()
+  }
+  // 从其他页面跳过来时,获取日期
+  function setDate() {
+    var date = moment(mbos.getRequestParams().date).format('YYYY-MM-DD')
+    if (date && mbos.getRequestParams().operateState == 'ADDNEW') {
+      mbos('entries_tripStartTime', 0).value(date + ' 08:00')
+      getStartEndTime(0)
+    }
+  }
+  
+  // 过滤出差类型F7 传递变量 ,dsQuery1为出差类型数据源的id
+  mbos('dsQuery1').bind('beforeLoad', function (e) {
+    var params = setParams('getTripTypeFilter', e.index) // 获取参数
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  
+  // 	在页面初始化加载之后
+  mbos('page').bind('afterLoad', function () {
+    _this.path = mbos.pageInfo.path// 轻应用的路径编码 例如 trip880
+    _this.detailPageCode = mbos.pageInfo.name.replace('Add', 'View') // 详情页面的编码 (个别页面可特殊处理直接写入) 例如 tripView.editui
+    _this.operateState = mbos.getRequestParams().operateState // 'ADDNEW' 'EDIT' 'VIEW'
+    // 初始化审批流
+    // mbos('nextperson1').checkParticipantPerson({
+    //   "callback": function () { }
+    // });
+    //   单据说明
+    mbos('description').bind('click', function () {
+      handleClickDesc()
+    })
+  })
+  mbos('entries').bind('afterRendered', function (e) {
+    showTimeZone(e.index)
+    multiLangField(e.index)// 兼容多语言字段回显的问题
+    if (e.index == 0) {
+      setDate()
+      // 初始化审批流
+        _this.getNextPerson();
+    }
+  })
+  // 初始化审批流
+  _this.getNextPerson = function(){
+    var entries = setModel('getNextPerson');
+    var data = JSON.parse(JSON.stringify(mbos('entity').value()));
+    data.entries = JSON.parse(JSON.stringify(entries));
+    var date = mbos.getRequestParams().date || new Date()
+    var today = moment(date).format('YYYY-MM-DD')
+    var beginTime = today + ' 00:00';
+    var endTime = today + ' 23:59';
+    mbos.eas.invokeScript({
+      name: "getHROrgUnit",
+      param: [{'beginTime': beginTime, 'endTime':endTime}],
+      success: function (res) {
+        console.log(res)
+        if(res.hrOrgUnitId){
+          data.hrOrgUnit = res.hrOrgUnitId
+        }
+        mbos('nextperson1').checkParticipantPerson({
+          'editdata': data,
+          "callback": function () { }
+        });
+      }
+    })
+  }
+  // 是否展示时区
+  function showTimeZone(index) {
+    var callback = function (res) {
+      if (res.data == 'true') {
+        mbos('entries_timeZone', index).show()
+      }
+    }
+    setModel()
+    baseInterface('isShowTimezone', callback, index)
+  }
+  // 保存按钮
+  _this.save = function (event) {
+    var isok = true;
+    var entries = mbos('entity').data.entries
+    entries.map(function (entry) {
+      var  triptime = entry.triptime 
+      if(triptime < 1){
+              mbos.msgBox.showError("出差时长必需大于1小时!");
+              isok = false;
+              return;
+      }
+    });
+    if(isok){
+        setModel()
+        baseInterface('save', toView) // 调用保存接口
+    }
+  }
+  // 提交按钮
+  _this.submit = function (event) {
+    var isok = true;
+    var entries = mbos('entity').data.entries
+    entries.map(function (entry) {
+      var  triptime = entry.triptime 
+      if(triptime < 1){
+              mbos.msgBox.showError("出差时长必需大于1小时!");
+              isok = false;
+              return;
+      }
+    });
+    if(isok){
+    // 确认提交 弹框
+            mbos.ui.showConfirm({
+            title: localeResource.confirmSubmit,
+            iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
+            callback: function (data) {
+                if (data == 0) {     
+                    setModel()
+                    baseInterface('submit', toView) // 调用提交接口
+                }
+            }
+        });
+    }
+ }
+    
+  
+  
+  // 点击“保存、提交” 跳转页面
+  function toView(res) {
+    // 提交接口 返回的res.data为数组,取第一条数据
+    if (res.data.keyValue || (res.data.length > 0 && res.data[0].keyValue)) {
+      // 操作成功 提示弹框
+      mbos.ui.showInfo({
+        title: localeResource.succeed,
+        iconclass: "kdfont kdfont-zhuangtai_wancheng the_success",
+        callback: function () {
+          openPage(_this.path, _this.detailPageCode, { billID: res.data.keyValue || res.data[0].keyValue })
+        }
+      });
+    }
+  }
+  // 给隐藏的model赋值
+  function setModel(method) {
+    if (typeof _this.operateState != "undefined" && (_this.operateState === "ADDNEW" || _this.operateState === "EDIT")) {
+      var entries = mbos('entity').data.entries
+      entries.map(function (entry) {
+        entry.person = easContext.person
+        entry.position = easContext.position
+        entry.adminOrgUnit = easContext.position.adminOrgUnit
+        getEntries(entry,method) // 各单据处理分录数据
+      })
+      return entries
+    }
+  }
+  // 各单据处理分录数据的函数
+  function getEntries(entry,method) {
+    entry.startTimeHMS = entry.tripStartTime
+    entry.endTimeHMS = entry.tripEndTime
+    if(method == 'getNextPerson'){
+      // entry.position = easContext.position.id;
+      // entry.adminOrgUnit = easContext.position.adminOrgUnit.id;
+      if(entry.startTimeHMS){
+        entry.startTimeHMS = moment(entry.startTimeHMS).format('YYYY-MM-DD HH:mm:ss')
+      }
+      if(entry.tripStartTime){
+        entry.tripStartTime = moment(entry.tripStartTime).format('YYYY-MM-DD HH:mm:ss')
+      }
+      if(entry.endTimeHMS){
+        entry.endTimeHMS = moment(entry.endTimeHMS).format('YYYY-MM-DD HH:mm:ss')
+      }
+      if(entry.tripEndTime){
+        entry.tripEndTime = moment(entry.tripEndTime).format('YYYY-MM-DD HH:mm:ss')
+      }
+    }else{
+      // delete entry.position;
+      // delete entry.adminOrgUnit;
+      
+    }
+  }
+  // 计算单据时长
+  function getTimeLength(index) {
+    var callback = function (res) {
+      mbos('entries_tripDays', index).value(res.data)
+    }
+    setModel(index)
+    var entry = mbos('entity').data.entries[index]
+    if (entry.tripEndTime && entry.tripStartTime) {
+      baseInterface('getBillLength', callback, index)
+    }
+  }
+  // 根据时间判断 是否展示弹性算时长字段
+  function isElastic(index) {
+    var callback = function (res) {
+      if (res.data) {
+        mbos('entries_isElasticCalLen', index).show()
+      }
+    }
+    setModel(index)
+    var entry = mbos('entity').data.entries[index]
+    if (entry.tripEndTime && entry.tripStartTime) {
+      baseInterface('showIsElasticCalCtrl', callback, index)
+    }
+  }
+  // 获取整天的开始、结束时间
+  function getStartEndTime(i) {
+    var callback = function (res) {
+      mbos('entries_tripStartTime', i).value(moment(res.data.beginTime).format('YYYY-MM-DD HH:mm'))
+      mbos('entries_tripEndTime', i).value(moment(res.data.endTime).format('YYYY-MM-DD HH:mm'))
+      
+    }
+    if (mbos('entries_tripStartTime', i).value() || mbos('entries_tripEndTime', i).value()){
+      setModel(i)
+      var params = _.cloneDeep(mbos('entity').data)
+      var endTime = params.entries[i].tripEndTime
+      if (endTime && endTime.includes('00:00')) { // 防止结束日期会一直触发 
+        params.entries[i].tripEndTime = moment(endTime).subtract(1, "minutes").format("YYYY-MM-DD HH:mm")
+      }
+      // 【BT-01684276】改为传一条分录数据
+      params.entries = [params.entries[i]];
+      baseInterface('getAllDayBeginAndEndTime', callback, i, params)
+    }
+  }
+  
+  // 如果是整天出差 则使用date;否则使用datetime,同时清空时长
+  function recalcTime(event) {
+    mbos('entries_tripDays', event.index).value('')
+    if (String(event.new_value) == 'true') {
+      var entry = mbos('entity').data.entries[event.index]
+      if (entry.tripEndTime || entry.tripStartTime) {
+        getStartEndTime(event.index) // 获取pc端配置的起止时间
+        //  _this.startHadCalculate = true // 阻止二次触发 出差单整天时 开始时间触发问题
+        // _this.endHadCalculate = true // 阻止二次触发
+      }
+    }
+  }
+  
+  // 计算时长
+  _this.calTime1 = function (event) {
+    getTimeLength(event.index)
+    isElastic(event.index)
+    if (String(mbos('entries_isAllDay', event.index).value()) == 'true' && !Boolean(_this.startHadCalculate)) {
+      getStartEndTime(event.index)
+      // _this.startHadCalculate = true // 阻止二次触发
+    } else {
+      _this.startHadCalculate = false
+    }
+      console.log('startHadCalculate', _this.startHadCalculate)
+  }
+  _this.calTime2 = function (event) {
+    getTimeLength(event.index)
+    isElastic(event.index)
+    if (String(mbos('entries_isAllDay', event.index).value()) == 'true' && !Boolean(_this.endHadCalculate)) {
+      getStartEndTime(event.index)
+      // _this.endHadCalculate = true// 阻止二次触发
+    } else {
+      _this.endHadCalculate = false
+    }
+      console.log('endHadCalculate', _this.endHadCalculate)
+  }
+  // 监听是否整天
+  _this.calTime3 = function (event) {
+    getTimeLength(event.index)
+    recalcTime(event)
+  }
+  // 监听弹性
+  _this.calTime4 = function (event) {
+    getTimeLength(event.index)
+  }
+  
+  // 时长更改时 做校验
+  _this.lengthChange = function(event){
+    var value = event.new_value
+    //   判断是否小于0
+    if (!isNaN(parseFloat(value)) && value < 0) {
+      mbos.msgBox.showError(localeResource.lengthValid);
+      setTimeout(()=>{
+        mbos('entries_tripDays',event.index).value(0)
+        mbos('entries_triptime', event.index).value(0);
+      })
+      return
+    }
+
+    //202412  向上取整
+    var triptime = mbos('entries_tripDays', event.index).value() * 7;
+    mbos('entries_triptime', event.index).value(Math.ceil(triptime));
+    
+  }
+          
+  

+ 75 - 0
mbos/我要出差_查看.js

@@ -0,0 +1,75 @@
+// 	在页面初始化加载之后  
+mbos('page').bind('afterLoad', function () {
+    _this.operateState = mbos.getRequestParams().operateState // 页面状态
+    _this.path = mbos.pageInfo.path // 轻应用的路径编码
+    _this.editPageCode = mbos.pageInfo.name.replace('View', 'Add') // 详情页面的编码 (个别页面可特殊处理直接写入)
+    _this.title = localeResource.Travel_Request
+    toggleEntry() // 折叠\展开实体分录
+    toggleApprove() // 折叠\展开 审批流程
+    
+     _this.decimal = 4
+    getDecimal()// 获取pc配置的小数点数
+  })
+  mbos('entity').bind('afterLoad', function () {
+    initCommon(_this.title)// 初始化公共部分
+  })
+  
+  mbos('editgrid1').bind('afterRendered', function (e) {
+    activedEntry() // 保证蓝色的下标在对应分录上
+    var index = e.index
+    initPage() // 页面初始化时数据调整
+    timeStyle(e) // 起止时间的样式优化展示
+    // 是否展示弹性算时长字段
+    ////202412  向上取整
+    var olddays =(mbos('timeLengthValue', index).value()).toFixed(_this.decimal);
+    var resultval = Math.ceil(olddays * 7); 
+    mbos('entries_isElasticCalLen', index).value() ? mbos('entries_isElasticCalLen', index).show(): mbos('entries_isElasticCalLen', index).hide()
+    $('#timeLength_' + index).find('label')[0].innerHTML = resultval + "小时";
+    $("[id^='entries_remark'] textarea").attr('rows', 3) // 多行文本 默认3行
+    $("[id^='entries_tripReason'] textarea").attr('rows', 3) // 多行文本 默认3行
+  })
+  // 获取pc配置的小数点数 默认为小数点后四位
+  function getDecimal(i){
+    var callback = function(res){
+      _this.decimal = res.data.decimalPlaceSystem || 4
+      
+    }
+    baseInterface('getDecimalPlace', callback) // 获取小数点数
+  }
+  // 编辑
+  _this.edit = function (event) {
+    editHandle(_this.path, _this.editPageCode)
+  }
+  // 删除
+  _this.delete = function (event) {
+    deleteHandle()
+  }
+  
+  // 撤回
+  _this.recall = function (event) {
+    // 未审批
+    recallHandle()
+  }
+  
+  // 提交
+  _this.toSubmit = function (event) {
+    submitHandle()
+  }
+  
+  // 分录中 时间的样式优化展示
+  function timeStyle(e) {
+    //   开始时间
+    var start = mbos('startTime', e.index).value().split(" ");
+    $('#sTime_' + e.index).find('label')[0].innerHTML = start[1];
+    $('#sDate_' + e.index).find('label')[0].innerHTML = start[0];
+    // 结束时间
+    var end = mbos('endTime', e.index).value().split(" ");
+    $('#eTime_' + e.index).find('label')[0].innerHTML = end[1];
+    $('#eDate_' + e.index).find('label')[0].innerHTML = end[0];
+    // 时长及箭头图标
+    $('#timeLength_' + e.index).find('label')[0].innerHTML = mbos('timeLengthValue', e.index).value() + localeResource.days;
+    $('#timeLength_' + e.index).find('label').addClass("lengthBottom");
+    $("#arrow_" + e.index).find('label').addClass("arrowIcon");
+  }
+          
+  

+ 455 - 0
mbos/我要加班.js

@@ -0,0 +1,455 @@
+_this.pageinit = function () {
+    var that = _this
+    _this.editInit = []
+    newPageInit(that)
+  }
+  
+  // 过滤考勤地点F7 传递变量 ,adminOrgQuery为数据源的id
+  mbos('adminOrgQuery').bind('beforeLoad', function (e) {
+    var params = setParams('getAtsAdminOrgUnitPlaceFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  // 过滤加班原因F7
+  mbos('AtsOTReasonAvailable').bind('beforeLoad', function (e) {
+    var params = setParams('getOverTimeReasonFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  // 过滤加班类型F7
+  mbos('AtsOTTypeAvailable').bind('beforeLoad', function (e) {
+    var params = setParams('getOverTimeTypeFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  // 过滤补偿方式F7
+  mbos('AtsOTCompensAvailable').bind('beforeLoad', function (e) {
+    var params = setParams('getOverTimeCompensFilter', e.index)
+    mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
+  })
+  
+  // 	在页面初始化加载之后
+  mbos('page').bind('afterLoad', function () {
+    _this.path = mbos.pageInfo.path// 轻应用的路径编码 例如 trip880
+    _this.detailPageCode = mbos.pageInfo.name.replace('Add', 'View') // 详情页面的编码 (个别页面可特殊处理直接写入) 例如 tripView.editui
+    _this.operateState = mbos.getRequestParams().operateState // 'ADDNEW' 'EDIT' 'VIEW'
+    // 初始化审批流
+    mbos('nextperson1').checkParticipantPerson({
+      "callback": function () { }
+    });
+    //   单据说明
+    mbos('description').bind('click', function () {
+      handleClickDesc()
+    })
+    getDecimal()// 获取pc配置的小数点数
+  })
+  
+  mbos('entries').bind('afterRendered', function (e) {
+    _this.decimal = 4
+    getBillDetail(e.index) // 编辑页面渲染数据
+    getDateType(e.index)// 判断加班日期是单选还是多选还是日期区间
+    mbos('entries_applyOTTime', e.index).value() && (mbos('entries_applyOTTime', e.index).value()).toFixed(_this.decimal)
+    multiLangField(e.index)// 兼容多语言字段回显的问题
+  })
+  
+  
+  // 获取pc配置的小数点数 默认为小数点后两位
+  function getDecimal() {
+    var callback = function (res) {
+      _this.decimal = res.data.decimalPlaceSystem || 4
+    }
+    baseInterface('getDecimalPlace', callback) // 获取小数点数
+  }
+  // 判断加班日期是单选还是多选还是日期区间
+  function getDateType(i) {
+    var entry = mbos('entity').data.entries[i] // 当前明细数据
+    if (mbos('theOtDate', 0).$attrs.datemulti == 'true') {
+      _this.otDateType = 'dateMulti'
+      _this.isMulDays = true
+      mbos('entries.attAdminOrgUnit', i).hide() // 多日期隐藏考勤地点
+    } else if (mbos('theOtDate', 0).$attrs.datescope == 'true') {
+      _this.otDateType = 'dateScope'
+      _this.isMulDays = true
+      mbos('entries.attAdminOrgUnit', i).hide() // 多日期隐藏考勤地点
+    } else {
+      _this.otDateType = 'dateSingle'
+      _this.isMulDays = false
+      entry.isMulDays = false
+      mbos('theOtDateCoordinate', i).hide() // 单日期隐藏跨天
+      $('#theOtTime_' + i + ' .tooltip1').hide() // 单日期隐藏时间提示
+      mbos('theOtDateCoordinate', i).attr("mustinput", false) // 取消必填校验
+    }
+    if (mbos.getRequestParams().operateState === "ADDNEW") {
+      //   给【是否跨天】赋默认值【不跨天】
+      mbos('theOtDateCoordinate', i).value({ "value": "theDayNow", "alias": localeResource.just_today })
+    }
+  }
+  // 将时间格式化为时分
+  function getHMTime(time) {
+    return moment(time).format('HH:mm')
+  }
+  // 编辑页面渲染数据
+  function getBillDetail(i) {
+    var entry = mbos('entity').data.entries[i]
+    entry.otDate && mbos('theOtDate', i).value(moment(entry.otDate).format('YYYY-MM-DD'))
+    if (!_this.isMulDays) { getDateType(i) } // 未初始化时 _this.isMulDays可能为undefined
+    console.log(entry.startTime, i, entry.endTime, mbos('entity').data.entries)
+    if (_this.isMulDays) { // 多日期 时间的格式为时分
+      entry.endTime && mbos('theOtTime', i).value(getHMTime(entry.startTime) + '~' + getHMTime(entry.endTime))
+      entry.restStartTime && mbos('theRestInterval', i).value(getHMTime(entry.restStartTime) + '~' + getHMTime(entry.restEndTime))
+      entry.restStartTime2 && mbos('theRestInterval2', i).value(getHMTime(entry.restStartTime2) + '~' + getHMTime(entry.restEndTime2))
+    } else {
+      entry.restTime &&  mbos('restTime', i).value(entry.restTime)
+      entry.endTime && mbos('theOtTime', i).value(entry.startTime + '~' + entry.endTime)                        // 给加班时间赋值
+      entry.restStartTime && mbos('theRestInterval', i).value(entry.restStartTime + '~' + entry.restEndTime)      // 给休息时间赋值
+      entry.restStartTime2 && mbos('theRestInterval2', i).value(entry.restStartTime2 + '~' + entry.restEndTime2)  // 给休息时间2赋值
+    }
+  }
+  
+  
+  // 保存按钮
+  _this.save = function (event) {
+    setModel()
+    baseInterface('save', toView) // 调用保存接口
+  }
+  // 提交按钮
+  _this.submit = function (event) {
+      // 确认提交 弹框
+    mbos.ui.showConfirm({
+      title: localeResource.confirmSubmit,
+      iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
+      callback: function (data) {
+        if (data == 0) {
+          setModel()
+          baseInterface('submit', toView) // 调用提交接口
+        }
+      }
+    });
+    
+  }
+  
+  // 点击“保存、提交” 跳转页面
+  function toView(res) {
+    // 提交接口 返回的res.data为数组,取第一条数据
+    if (res.data.keyValue || (res.data.length > 0 && res.data[0].keyValue)) {
+          // 操作成功 提示弹框
+      mbos.ui.showInfo({
+        title: localeResource.succeed,
+        iconclass: "kdfont kdfont-zhuangtai_wancheng the_success",
+        callback: function () {
+          openPage(_this.path, _this.detailPageCode, { billID: res.data.keyValue || res.data[0].keyValue })
+        }
+      });
+      
+    }
+  }
+  // 给隐藏的model赋值
+  function setModel() {
+    if (typeof _this.operateState != "undefined" && (_this.operateState === "ADDNEW" || _this.operateState === "EDIT")) {
+      var entries = mbos('entity').data.entries
+      entries.map(function (entry, index) {
+        entry.person = easContext.person
+        entry.position = easContext.position.id
+        entry.adminOrgUnit = easContext.position.adminOrgUnit.id
+        getEntries(entry, index) // 各单据处理分录数据
+      })
+    }
+  }
+  
+  
+  
+  // 各单据处理分录数据的函数
+  function getEntries(entry, i) {
+    //   跨天方式
+    if (mbos('theOtDateCoordinate', i).value()) {
+      entry.theOtDateCoordinate = mbos('theOtDateCoordinate', i).value().value
+    }
+    entry.isMulDays = _this.isMulDays
+    entry.otDate = _this.isMulDays ? entry.dynamic_Field1 && entry.dynamic_Field1.split(',')[0] : entry.otDate || entry.theOtDate || mbos('theOtDate', i).value() // 加班日期
+    // 【BT-01701321】【V9.0第一轮集成测试】移动端撤回加班单后修改休息时间再提交,休息时间和加班小时数不正确。修改为休息时长60min后,再修改为休息时间0,提交后休息时间还是60
+    if(entry.restTime === undefined){
+      entry.restTime = ''
+    }
+  } 
+  // 单日期 获取默认加班类型和补偿方式
+  function getOverTimeTypeAndOtCompens(index) {
+    var callback = function (res) {
+      if (res.data) {
+        if (res.data.otTypeValue && res.data.otTypeText){
+          mbos('entries_otType', index).value({ id: res.data.otTypeValue, name: res.data.otTypeText })
+        } else {
+           mbos.ui.showError(localeResource.checkShift)
+        }
+        res.data.compensInfo && mbos('entries_otCompens', index).value(res.data.compensInfo)
+      }
+    }
+    setModel()
+    baseInterface('getOverTimeTypeAndOtCompens', callback, index)
+  }
+  // 单日期 获取加班班次
+  function getMyScheduleTime(index) {
+    var callback = function (res) {
+  //     默认班次存在则显示 不存在则隐藏
+      if (res.data && res.data.defaultShift && res.data.defaultShift.name) {
+        document.getElementById('attendanceShift_' + index).innerText = `${res.data.defaultShift.name}`
+        $('#attendanceShift_' + index).css('display', 'flex')
+      } else {
+        document.getElementById('attendanceShift_' + index).innerText = ''
+        $('#attendanceShift_' + index).css('display', 'none')
+      }
+    }
+    setModel()
+    baseInterface('getMyScheduleTime', callback, index)
+  }
+  // 根据起始时间计算休息分钟数
+  function getDiffMinites(sTime, eTime, hour) {
+    if (sTime && eTime) {
+      // 通过正则将'-'改为'/'(ios系统不认得'-'却认得'/')
+      var date1 = new Date(sTime.replace(/-/g, '/')).getTime()
+      var date2 = new Date(eTime.replace(/-/g, '/')).getTime()
+      if (sTime.split(' ')[1] && date1 > date2) { // 单日期 计算时间才需要判断
+        mbos.ui.showError(hour ? localeResource.ot_tips : localeResource.rest_tips)
+        return 
+      }
+      return hour ? Math.abs((date2 - date1) / 1000 / 60 / 60) : Math.abs((date2 - date1) / 1000 / 60)
+    }
+  }
+  // 获取默认休息时间
+  function getDefaultRestTime(index) {
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    var callback = function (res) {
+      if (res.data) {      //         如果无值则渲染 有值则不予更改,用户手动填写的数据优先级最高
+        if (!mbos('theRestInterval', index).value()) {
+          if (res.data.restEndTime) {
+            entry.restTime = res.data.restTime
+            mbos('theRestInterval', index).value(res.data.restStartTime + '~' + res.data.restEndTime)
+          } else {
+            // mbos('theRestInterval', index).value('')
+            entry.restStartTime = ''
+            entry.restEndTime = ''
+          }
+        }
+        //     休息时间2    如果无值则渲染 有值则不予更改,用户手动填写的数据优先级最高
+        if (!mbos('theRestInterval2', index).value()) {
+          if (res.data.restEndTime2) {
+            entry.restTime = res.data.restTime
+            !mbos('theRestInterval2', index).value() && mbos('theRestInterval2', index).value(res.data.restStartTime2 + '~' + res.data.restEndTime2)
+          } else {
+            // mbos('theRestInterval2', index).value('')
+            entry.restStartTime2 = ''
+            entry.restEndTime2 = ''
+          }
+        }
+        // entry.applyOTTime = ((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0).toFixed(_this.decimal) // 加班时长
+        //  202412  加班时长改为小时数向下取整
+        entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0) ;
+
+      }
+    }
+    if (_this.otDateType == 'dateSingle' && entry.theOtDate) {
+      setModel()
+      baseInterface('getMyRestTime', callback, index)
+    }
+  }
+  // 单日期时判断”加班类型“是否是被禁用
+  function isDisabledDateType(otDate, index) {
+    var callback = function (res) {
+      if (res.data.otrolByDateType) {
+        mbos('entries_otType', index).disable() // 如果返回为true 则禁用
+      } else {
+        mbos('entries_otType', index).attr('disabled', false)
+      }
+    }
+    if (otDate) {
+      setModel()
+      baseInterface('getAttencePolicyInfo', callback, index)
+    }
+  }
+  /**
+   * @description: 根据开始日期结束日期的时区,获取逗号拼接的日期字符串
+   * @return {String}
+   */
+  function getDates(sDate, eDate) {
+    var list = [sDate]
+    var value = sDate
+    while (value < eDate) {
+      value = moment(value).add(1, 'days').format('YYYY-MM-DD')
+      list.push(value)
+    }
+    return list.join(',')
+  }
+  // 非单日期 日期change事件
+  function multiDateChange(dateString, entry, index) {
+    entry.isMulDays = true
+    entry.otDates = dateString
+    entry.theOtDateCoordinate = 'theDayNow'
+    entry.days = dateString.split(',').length // 天数
+    entry.restTime = (getDiffMinites(entry.restStartTime, entry.restEndTime) + getDiffMinites(entry.restStartTime2, entry.restEndTime2)) * entry.days || 0
+    // entry.applyOTTime = ((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0).toFixed(_this.decimal)
+    // 202412  加班时长改为小时数向下取整
+    entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0); 
+    // 校验多选日期是否是同一时间类型 如果不是则清空
+    var callback = function (res) {
+      if (res.data && !res.data.isSameDay) {
+        mbos.ui.showError({
+          title:  localeResource.tips,
+          detail: localeResource.diff_type_tips,
+          iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
+          callback: function (data) {
+            mbos('theOtDate', index).value(''); // 先清空
+            mbos('theOtDate', index).open(); // 再自动打开弹框
+          }
+        });
+      }
+    }
+    if (entry.days > 1) {
+      setModel()
+      baseInterface('getDateTypeIsSame', callback, index) // 校验多选日期是否是同一时间类型
+    }
+    // mbos('theOtTime', index).timeFormat("HH:mm")
+  }
+  /**
+   * @description: 监听加班日期;
+   * 单日期则改变 加班开始/结束时间、加班时间;
+                休息开始/结束时间、休息时间;
+                休息时长、加班时长
+                加班类型\加班补偿方式\加班日期班次
+    * 
+    * 多选日期/时间区间 则改变:休息时长、加班时长
+    * 
+    1、pc端配置的默认加班时间;
+    2、默认休息时间;
+    3、加班类型、补偿方式接口;
+    4、带出对应班次;
+  【以上接口仅单日期触发】 【EDIT页面初始化时,不调以上4个接口】
+    * @return {*}
+    */
+  _this.otDateChange = function (event) {
+    var index = event.index
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    var theOtDate = event.new_value // 加班日期
+    if (!_this.otDateType) {
+      getDateType(index)
+    }
+    if (!theOtDate) {
+      mbos('theOtTime', index).value('')
+      return
+    }
+    var otDateType = _this.otDateType // 日期类型
+    if (otDateType == 'dateScope') { // 日期区间
+      if (theOtDate) {
+        var sDate = moment(theOtDate.split('~')[0]).format('YYYY-MM-DD')
+        var eDate = theOtDate.split('~')[1] ? theOtDate.split('~')[1] : sDate
+        theOtDate = getDates(sDate, eDate)
+        multiDateChange(theOtDate, entry, index)
+      }
+    } else if (otDateType == 'dateMulti') { // 多选日期
+      multiDateChange(theOtDate, entry, index)
+    } else if (otDateType == 'dateSingle') { // 单选日期
+      if (event.new_value && event.old_value && moment(event.new_value).format('YYYY-MM-DD') === moment(event.old_value).format('YYYY-MM-DD')) return
+      theOtDate = moment(theOtDate).format('YYYY-MM-DD')
+      entry.otDate = theOtDate
+      entry.theOtDate = theOtDate
+      entry.isMulDays = false
+      getMyScheduleTime(index) // 加班班次
+      isDisabledDateType(theOtDate, index)  // 待更新到外网
+      entry.days = 1
+      if (!entry.startTime && !entry.endTime) {
+        // 加班时间【00:00】 二开用户可自定义
+        mbos('theOtTime', index).value(theOtDate + ' 00:00~' + theOtDate + ' 00:00') // 给加班时间赋默认值
+      } 
+      getOverTimeTypeAndOtCompens(index) // 加班类型&补偿类型
+      getDefaultRestTime(index) // 获取默认休息时间
+    }
+  }
+  /**
+   * @description: 监听加班时间:默认休息时间(调接口)
+   * @event: applyOTTime = otIntervalLength - restTime => 加班时长 = 跨度时长 - 休息时长
+   * @return {*}
+   */
+  _this.otTimeChange = function (event) {
+    var index = event.index
+    var theOtTime = event.new_value // 加班时间
+    var startTime = theOtTime.split('~')[0]
+    var endTime = theOtTime.split('~')[1]
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    _this.anyDate = entry.otDates && entry.otDates.split(',')[0] || '2020-01-01' // 仅作拼接使用 无任何意义
+    if (!theOtTime) {
+      entry.applyOTTime = 0
+    }
+    startTime = _this.isMulDays ? _this.anyDate + ' ' + startTime : startTime // 确保 格式为年月日时分
+    endTime = _this.isMulDays ? _this.anyDate + ' ' + endTime : endTime // 确保 格式为年月日时分   同一天
+    if (startTime > endTime) { // 跨天
+      var tomorrow = moment(_this.anyDate).add(1, 'days').format('YYYY-MM-DD')
+      endTime = _this.isMulDays ? tomorrow + ' ' + endTime : endTime  // 确保 格式为年月日时分
+    }
+  
+    entry.startTime = startTime // 赋值加班开始时间
+    entry.endTime = endTime // 赋值加班结束时间
+    entry.otIntervalLength = getDiffMinites(startTime, endTime, 'hour') // 加班的一天跨度时长
+  
+    if (!entry.days) entry.days = 1
+    // entry.applyOTTime = ((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0).toFixed(_this.decimal) // 加班时长
+    //202412改 向下取整
+    entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0) ; // 加班时长
+  
+    if (mbos.getRequestParams().operateState !== 'EDIT' || _this.init) {
+      getDefaultRestTime(index) // 更新休息时间
+    } else {
+      _this.init = true
+    }
+  }
+  /**
+   * @description: 监听【休息时间1】改变时长
+   * @event: 
+   * @return {*}
+   */
+  _this.restTimeChange = function (event) {
+    restChange(event, "restStartTime", "restEndTime", "restTime1")
+  }
+  
+  // 监听【休息时间2】改变时长
+  _this.restTimeChange2 = function (event) {
+    restChange(event, "restStartTime2", "restEndTime2", "restTime2")
+  }
+  // 休息时间控件监听 start, end, time分别为对应的字段名
+  function restChange(event, start, end, time) {
+    var index = event.index
+    //   如果两个休息时间都为空,则时间长度可编辑;否则不可编辑
+    if (!mbos('theRestInterval', index).value() && !mbos('theRestInterval2', index).value()) {
+      mbos('entries_restTime', index).enable()
+    } else {
+      mbos('entries_restTime', index).disable()
+    }
+  
+    _this.anyDate = '2020-01-01' // 仅作拼接使用 无任何意义
+  
+    var theRestInterval = event.new_value // 休息时间
+    var startTime = theRestInterval.split('~')[0]
+    var endTime = theRestInterval.split('~')[1]
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+  
+    var notToday = startTime > endTime  // 如果开始时间大于结束时间则表示跨天了
+    entry[start] = _this.isMulDays ? _this.anyDate + ' ' + startTime : startTime // 确保 格式为年月日时分
+    var tomorrow = moment(_this.anyDate).add(1, 'days').format('YYYY-MM-DD')
+    entry[end] = _this.isMulDays ? (notToday ? tomorrow + ' ' + endTime : _this.anyDate + ' ' + endTime) : endTime // 确保 格式为年月日时分
+    entry[time] = theRestInterval ? getDiffMinites(entry[start], entry[end]) * (entry.days || 1) : 0
+    if (entry.restTime1 == 0 && entry.restTime2 == 0) {
+      entry.restTime = entry.restTime || 0
+    } else {
+      entry.restTime = (entry.restTime1 || 0) + (entry.restTime2 || 0)
+    }
+    
+    // entry.applyOTTime = ((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0).toFixed(_this.decimal) // 加班时长
+    // 202412改 向下取整
+    entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0) ; // 加班时长
+  
+  }
+  // 休息时长改动
+  _this.restLengthChange = function (event) {
+    var index = event.index
+    var entry = mbos('entity').data.entries[index] // 当前明细数据
+    if (mbos('entries_applyOTTime', index).value()) {
+      // entry.applyOTTime = (entry.otIntervalLength * entry.days - (event.new_value || 0) / 60 || 0).toFixed(_this.decimal)
+      // 202412改 向下取整
+      entry.applyOTTime = Math.floor( (entry.otIntervalLength * entry.days - (event.new_value || 0) / 60 || 0) );
+    }
+  }
+      

+ 441 - 0
websrc/com/kingdee/shr/ats/web/util/AtsOverTimeBillUtils.java

@@ -0,0 +1,441 @@
+package com.kingdee.shr.ats.web.util;
+
+import com.kingdee.bos.BOSException;
+import com.kingdee.bos.Context;
+import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
+import com.kingdee.bos.util.BOSUuid;
+import com.kingdee.eas.basedata.person.PersonFactory;
+import com.kingdee.eas.basedata.person.PersonInfo;
+import com.kingdee.eas.common.EASBizException;
+import com.kingdee.eas.hr.ats.AtsFileBizException;
+import com.kingdee.eas.hr.ats.AtsOTBizException;
+import com.kingdee.eas.hr.ats.AtsOverTimeBillEntryCollection;
+import com.kingdee.eas.hr.ats.AtsOverTimeBillEntryInfo;
+import com.kingdee.eas.hr.ats.AtsOverTimeBillInfo;
+import com.kingdee.eas.hr.ats.AtsOverTimeBillResEnum;
+import com.kingdee.eas.hr.ats.AtsShiftInfo;
+import com.kingdee.eas.hr.ats.AtsUtil;
+import com.kingdee.eas.hr.ats.AttencePolicyInfo;
+import com.kingdee.eas.hr.ats.AttendanceFileHISInfo;
+import com.kingdee.eas.hr.ats.AttendanceFileInfo;
+import com.kingdee.eas.hr.ats.DayTypeEnum;
+import com.kingdee.eas.hr.ats.OverTimeCompensCollection;
+import com.kingdee.eas.hr.ats.OverTimeCompensFactory;
+import com.kingdee.eas.hr.ats.OverTimeCompensInfo;
+import com.kingdee.eas.hr.ats.OverTimeTypeFactory;
+import com.kingdee.eas.hr.ats.OverTimeTypeInfo;
+import com.kingdee.eas.hr.ats.ScheduleShiftInfo;
+import com.kingdee.eas.hr.ats.WorkCalendarItemCollection;
+import com.kingdee.eas.hr.ats.WorkCalendarItemFactory;
+import com.kingdee.eas.hr.ats.decimalPlace.util.DecimalPlaceUtil;
+import com.kingdee.eas.hr.ats.util.AtsDateUtils;
+import com.kingdee.eas.hr.ats.util.AtsScheduleShiftUtil;
+import com.kingdee.eas.hr.ats.util.common.MLUtile;
+import com.kingdee.shr.ats.bill.util.AtsOverTimeBillHelper;
+import com.kingdee.shr.ats.bill.util.FillSignCardHelper;
+import com.kingdee.shr.ats.service.common.AtsWebBizException;
+import com.kingdee.shr.ats.service.move.ot.OverTimeBillOsfProcessor;
+import com.kingdee.shr.base.syssetting.exception.SHRWebException;
+import com.kingdee.shr.base.syssetting.exception.ShrWebBizException;
+import java.math.BigDecimal;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.apache.axis.utils.StringUtils;
+import org.apache.log4j.Logger;
+
+public class AtsOverTimeBillUtils {
+	private static Logger logger = Logger.getLogger("com.kingdee.shr.ats.web.util.AtsOverTimeBillUtils");
+
+	public Map<String, Object> getDateTypeIsSame(Context ctx, String personId, List<Date> otDateList)
+			throws BOSException {
+		Map<String, Object> res = new HashMap();
+		boolean flag = true;
+		DayTypeEnum oldDayType = null;
+
+		for (int index = 0; index < otDateList.size(); ++index) {
+			String otDate = AtsDateUtils.dateLongToString((Date) otDateList.get(index));
+			DayTypeEnum dayType = this.getDayType(ctx, personId, otDate);
+			res.put(otDate, dayType);
+			if (flag && oldDayType != null && oldDayType.getValue() != dayType.getValue()) {
+				flag = false;
+			}
+
+			oldDayType = dayType;
+		}
+
+		res.put(OverTimeBillOsfProcessor.IS_SANE_DAY, flag);
+		return res;
+	}
+
+	public DayTypeEnum getDayType(Context ctx, String personId, String otDate) {
+		if (personId != null && !"".equals(personId) && otDate != null && !"".equals(otDate)) {
+			try {
+				ScheduleShiftInfo scheduleShiftInfo = AtsScheduleShiftUtil.getScheduleShiftByPriority(ctx, personId,
+						otDate);
+				if (null != scheduleShiftInfo) {
+					DayTypeEnum dayTypeEnum = scheduleShiftInfo.getDayType();
+					return dayTypeEnum;
+				}
+
+				Date otDatee = AtsDateUtils.stringToShortDate(otDate);
+				AttendanceFileHISInfo hisInfo = FillSignCardHelper.getAttendanceFileHISInfoByAttenceDate(ctx, otDatee,
+						personId);
+				if (hisInfo != null && hisInfo.getCalendar() != null) {
+					WorkCalendarItemCollection itemColl = WorkCalendarItemFactory.getLocalInstance(ctx)
+							.getWorkCalendarItemCollection(" where date='" + otDate + "' and calendarGroup.id='"
+									+ hisInfo.getCalendar().getId().toString() + "'");
+					if (itemColl != null && itemColl.size() > 0) {
+						return itemColl.get(0).getDayType();
+					}
+				}
+			} catch (Exception var8) {
+				var8.printStackTrace();
+			}
+		}
+
+		return null;
+	}
+
+	public Map<String, Object> getOverTimeTypeMap(Context ctx, String personId, String otDate) {
+		Map<String, Object> res = new HashMap();
+		OverTimeTypeInfo overTimeType = this.getOverTimeType(ctx, personId, otDate);
+		if (overTimeType != null && overTimeType.getId() != null) {
+			res.put("otTypeValue", overTimeType.getId().toString());
+			res.put("otTypeText", overTimeType.getName());
+			return res;
+		} else {
+			return res;
+		}
+	}
+
+	public Map<String, Object> doGetOverTimeTypeAndOtCompens(Context ctx, String personId, String otDate)
+			throws BOSException {
+		if (otDate.length() == 19) {
+			otDate = otDate.substring(0, 10);
+		}
+
+		Map<String, Object> res = this.getOverTimeTypeMap(ctx, personId, otDate);
+		if (res.get("otTypeValue") == null) {
+			return res;
+		} else {
+			String overTimeId = (String) res.get("otTypeValue");
+			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+			Date otdates = null;
+
+			try {
+				otdates = sdf.parse(otDate);
+			} catch (Exception var9) {
+				var9.printStackTrace();
+			}
+
+			OverTimeCompensInfo defaultcompens = this.getdefautAndOtOTCompens(ctx, personId, overTimeId, otdates);
+			res.put("compensInfo", defaultcompens);
+			return res;
+		}
+	}
+
+	public OverTimeTypeInfo getOverTimeType(Context ctx, String personId, String otDate) {
+		OverTimeTypeInfo overTimeTypeInfo = null;
+		if (personId != null && !"".equals(personId) && otDate != null && !"".equals(otDate)) {
+			try {
+				ScheduleShiftInfo scheduleShiftInfo = AtsScheduleShiftUtil.getScheduleShiftByPriority(ctx, personId,
+						otDate);
+				if (null != scheduleShiftInfo) {
+					DayTypeEnum dayTypeEnum = scheduleShiftInfo.getDayType();
+					int dayType = dayTypeEnum.getValue();
+					overTimeTypeInfo = this.getOverTimeType(ctx, dayType);
+				} else {
+					Date otDatee = AtsDateUtils.stringToShortDate(otDate);
+					AttendanceFileHISInfo hisInfo = FillSignCardHelper.getAttendanceFileHISInfoByAttenceDate(ctx,
+							otDatee, personId);
+					if (hisInfo != null && hisInfo.getCalendar() != null) {
+						WorkCalendarItemCollection itemColl = WorkCalendarItemFactory.getLocalInstance(ctx)
+								.getWorkCalendarItemCollection(" where date='" + otDate + "' and calendarGroup.id='"
+										+ hisInfo.getCalendar().getId().toString() + "'");
+						if (itemColl != null && itemColl.size() > 0) {
+							int dayType = itemColl.get(0).getDayType().getValue();
+							overTimeTypeInfo = this.getOverTimeType(ctx, dayType);
+						}
+					}
+				}
+			} catch (Exception var10) {
+				var10.printStackTrace();
+			}
+		}
+
+		return overTimeTypeInfo;
+	}
+
+	private OverTimeTypeInfo getOverTimeType(Context ctx, int dayType) {
+		OverTimeTypeInfo overTimeType = new OverTimeTypeInfo();
+		String overTimeName;
+		if (dayType == 1) {
+			overTimeType.setId(BOSUuid.read("zr+ur5D4RA+2bdVZ2VPqp46C/nU="));
+			overTimeName = this.getOverTimeName(ctx, "zr+ur5D4RA+2bdVZ2VPqp46C/nU=");
+			overTimeType.setName(
+					overTimeName == null ? MLUtile.getRes(AtsOverTimeBillResEnum.WorkOnHoliday, ctx) : overTimeName);
+		} else if (dayType == 2) {
+			overTimeType.setId(BOSUuid.read("sRWUOt7sRpOY0TCo6NMqGY6C/nU="));
+			overTimeName = this.getOverTimeName(ctx, "sRWUOt7sRpOY0TCo6NMqGY6C/nU=");
+			overTimeType.setName(
+					overTimeName == null ? MLUtile.getRes(AtsOverTimeBillResEnum.WorkOnHoliday, ctx) : overTimeName);
+		} else {
+			overTimeType.setId(BOSUuid.read("rBy0u1YgQ9C1OxcM85mxyY6C/nU="));
+			overTimeName = this.getOverTimeName(ctx, "rBy0u1YgQ9C1OxcM85mxyY6C/nU=");
+			overTimeType.setName(
+					overTimeName == null ? MLUtile.getRes(AtsOverTimeBillResEnum.WorkOnHoliday, ctx) : overTimeName);
+		}
+
+		return overTimeType;
+	}
+
+	private String getOverTimeName(Context ctx, String id) {
+		String name = null;
+
+		try {
+			name = OverTimeTypeFactory.getLocalInstance(ctx).getOverTimeTypeInfo(new ObjectUuidPK(id)).getName();
+		} catch (Exception var5) {
+			var5.printStackTrace();
+		}
+
+		return name;
+	}
+
+	public OverTimeCompensInfo getdefautAndOtOTCompens(Context ctx, String personId, String otTypeId, Date otDate)
+			throws BOSException {
+		OverTimeCompensInfo defaultCompensInfo = null;
+		AttendanceFileHISInfo fileCol = FillSignCardHelper.getAttendanceFileHISInfoByAttenceDate(ctx, otDate, personId);
+		OverTimeCompensInfo defaultotCompens = null;
+		if ("rBy0u1YgQ9C1OxcM85mxyY6C/nU=".equals(otTypeId)) {
+			defaultotCompens = fileCol.getAttencePolicy().getDefaultotCompens1();
+		} else if ("zr+ur5D4RA+2bdVZ2VPqp46C/nU=".equals(otTypeId)) {
+			defaultotCompens = fileCol.getAttencePolicy().getDefaultotCompens2();
+		} else if ("sRWUOt7sRpOY0TCo6NMqGY6C/nU=".equals(otTypeId)) {
+			defaultotCompens = fileCol.getAttencePolicy().getDefaultotCompens3();
+		} else {
+			defaultotCompens = OverTimeCompensFactory.getLocalInstance(ctx).getOverTimeCompensCollection().get(0);
+		}
+
+		String defaultId = defaultotCompens == null ? "" : defaultotCompens.getId().toString();
+		if (!StringUtils.isEmpty(defaultId)) {
+			try {
+				defaultCompensInfo = OverTimeCompensFactory.getLocalInstance(ctx)
+						.getOverTimeCompensInfo(new ObjectUuidPK(defaultId));
+				if (defaultCompensInfo.getState().getValue() != 1) {
+					return null;
+				}
+			} catch (EASBizException var10) {
+				var10.printStackTrace();
+			}
+		}
+
+		return defaultCompensInfo;
+	}
+
+	public String getOTCompensByOTType(Context ctx, String personId, String otTypeId, String hrOrgUnit, Date otdate)
+			throws SHRWebException, BOSException {
+		PersonInfo person = null;
+
+		try {
+			person = PersonFactory.getLocalInstance(ctx).getPersonInfo(new ObjectUuidPK(personId));
+		} catch (EASBizException var14) {
+			throw new ShrWebBizException(
+					new AtsFileBizException(AtsFileBizException.FETCHPINFOERROR, new Object[]{personId}));
+		}
+
+		AttendanceFileHISInfo fileCol = FillSignCardHelper.getAttendanceFileHISInfoByAttenceDate(ctx, otdate, personId);
+		if (fileCol != null && fileCol.size() != 0) {
+			AttencePolicyInfo policyInfo = fileCol.getAttencePolicy();
+			if (policyInfo == null) {
+				throw new ShrWebBizException(
+						new AtsFileBizException(AtsFileBizException.NOATTPOLICY, new Object[]{person.getName()}));
+			} else if (policyInfo.getOtCompens1() != null && policyInfo.getOtCompens2() != null
+					&& policyInfo.getOtCompens3() != null) {
+				String otCompens = "";
+				if ("rBy0u1YgQ9C1OxcM85mxyY6C/nU=".equals(otTypeId)) {
+					otCompens = fileCol.getAttencePolicy().getOtCompens1().toString();
+				} else if ("zr+ur5D4RA+2bdVZ2VPqp46C/nU=".equals(otTypeId)) {
+					otCompens = fileCol.getAttencePolicy().getOtCompens2().toString();
+				} else if ("sRWUOt7sRpOY0TCo6NMqGY6C/nU=".equals(otTypeId)) {
+					otCompens = fileCol.getAttencePolicy().getOtCompens3().toString();
+				}
+
+				String enableotCompens;
+				OverTimeCompensCollection otCompensCollection;
+				String[] otCompensId;
+				int i;
+				if (!StringUtils.isEmpty(otCompens)) {
+					enableotCompens = "";
+					new OverTimeCompensCollection();
+					otCompensId = otCompens.split(",");
+					otCompensCollection = OverTimeCompensFactory.getLocalInstance(ctx).getOverTimeCompensCollection(
+							"where id in (" + AtsUtil.getStrFromStringArr(otCompensId) + ") and state = 1");
+
+					for (i = 0; i < otCompensCollection.size(); ++i) {
+						enableotCompens = enableotCompens + otCompensCollection.get(i).getId().toString();
+						if (i < otCompensCollection.size() - 1) {
+							enableotCompens = enableotCompens + ",";
+						}
+					}
+
+					if (!StringUtils.isEmpty(enableotCompens)) {
+						return enableotCompens;
+					}
+				} else {
+					enableotCompens = "";
+					new OverTimeCompensCollection();
+					otCompensId = otCompens.split(",");
+					otCompensCollection = OverTimeCompensFactory.getLocalInstance(ctx).getOverTimeCompensCollection(
+							"where id in (SELECT fbaseinfoID from T_ATS_AtsOTCompensAvailable where fhrorguseid = '"
+									+ hrOrgUnit + "' ) and state = 1");
+
+					for (i = 0; i < otCompensCollection.size(); ++i) {
+						enableotCompens = enableotCompens + otCompensCollection.get(i).getId().toString();
+						if (i < otCompensCollection.size() - 1) {
+							enableotCompens = enableotCompens + ",";
+						}
+					}
+
+					if (!StringUtils.isEmpty(enableotCompens)) {
+						return enableotCompens;
+					}
+				}
+
+				return otCompens;
+			} else {
+				throw new ShrWebBizException(
+						new AtsFileBizException(AtsFileBizException.NOOTCOMPENSTYPE, new Object[]{person.getName()}));
+			}
+		} else {
+			throw new ShrWebBizException(
+					new AtsFileBizException(AtsFileBizException.NOTEXISTEFFECTATTFILE, new Object[]{person.getName()}));
+		}
+	}
+
+	public void calApplyOTTime(Context ctx, AtsOverTimeBillInfo billInfo) {
+		try {
+			if (billInfo == null) {
+				return;
+			}
+
+			AtsOverTimeBillEntryCollection entries = billInfo.getEntries();
+			if (entries == null || entries.size() == 0) {
+				return;
+			}
+
+			AtsOverTimeBillEntryInfo entryInfo = null;
+			Timestamp startTime = null;
+			Timestamp endTime = null;
+		 
+			long l = 0L;
+			double divide = 0.0D;
+			int decimalPlaceSystem = DecimalPlaceUtil.getDecimalPlaceSystem(ctx);
+
+			for (int index = 0; index < entries.size(); ++index) {
+				entryInfo = entries.get(index);
+				startTime = entryInfo.getStartTime();
+				endTime = entryInfo.getEndTime();
+				int restTime = entryInfo.getRestTime();
+				l = endTime.getTime() - startTime.getTime() - (long) (restTime * 60 * 1000);
+//				if (l > 0L) {
+//					divide = AtsDateUtils.divide((double) l, 3600000.0D, decimalPlaceSystem, 6);
+//					entryInfo.setApplyOTTime(BigDecimal.valueOf(divide));
+//					entryInfo.setRealOTTime(entryInfo.getApplyOTTime());
+//				}
+				//2024 核子基因
+				if (l > 0L) {
+					divide = AtsDateUtils.divide((double) l, 3600000.0D, decimalPlaceSystem, 6);
+					double flooredValue = Math.floor(divide);
+					entryInfo.setApplyOTTime(BigDecimal.valueOf(flooredValue));
+					entryInfo.setRealOTTime(entryInfo.getApplyOTTime());
+				}
+			}
+		} catch (Exception var14) {
+			logger.error(var14);
+		}
+
+	}
+
+	public void setEntryAdminOrgAndPosition(Context ctx, AtsOverTimeBillInfo billInfo) throws SHRWebException {
+		if (null != billInfo.getEntries()) {
+			String hrOrgUnitId = billInfo.getHrOrgUnit().getId().toString();
+
+			for (int i = 0; i < billInfo.getEntries().size(); ++i) {
+				try {
+					AttendanceFileHISInfo hisInfo = FillSignCardHelper.getAttendanceFileHISInfoByAttenceDate(ctx,
+							billInfo.getEntries().get(i).getOtDate(),
+							billInfo.getEntries().get(i).getPerson().getId().toString());
+					if (hisInfo == null) {
+						throw new ShrWebBizException(AtsWebUtils.overtime_noFile_msg);
+					}
+
+					if (!hrOrgUnitId.equals(hisInfo.getHrOrgUnit().getId().toString())) {
+						String attDateStr = AtsDateUtils.dateShortToString(billInfo.getEntries().get(i).getOtDate());
+						throw new AtsWebBizException(new AtsOTBizException(AtsOTBizException.NOMATCHHRORGORDATE,
+								new Object[]{hisInfo.getProposer().getName(), hisInfo.getProposer().getNumber(),
+										attDateStr, hisInfo.getHrOrgUnit().getDisplayName(),
+										AtsDateUtils.dateShortToString(hisInfo.getEFFDT()),
+										AtsDateUtils.dateShortToString(hisInfo.getLEFFDT())}));
+					}
+
+					billInfo.getEntries().get(i).setAdminOrgUnit(hisInfo.getAdminOrgUnit());
+					billInfo.getEntries().get(i).setPosition(hisInfo.getPosition());
+				} catch (BOSException var7) {
+					throw new SHRWebException(var7.getMessage());
+				}
+			}
+
+		}
+	}
+
+	public Map<String, Object> doIsOTCompensEffective(Context ctx, String OTCompenId)
+			throws EASBizException, BOSException, SQLException {
+		AtsOverTimeBillHelper aoh = new AtsOverTimeBillHelper();
+		boolean resFlag = aoh.isOTCompensEffect(ctx, OTCompenId);
+		Map<String, Object> res = new HashMap();
+		res.put("resFlag", resFlag);
+		return res;
+	}
+
+	public ScheduleShiftInfo getMyScheduleTime(Context ctx, String personId, String date) {
+		List<ScheduleShiftInfo> scheduleTime = this.getScheduleTime(ctx, personId, date, date);
+		return scheduleTime != null && scheduleTime.size() != 0 ? (ScheduleShiftInfo) scheduleTime.get(0) : null;
+	}
+
+	public List<ScheduleShiftInfo> getScheduleTime(Context ctx, String personId, String preDate, String nextDate) {
+		List<ScheduleShiftInfo> scheduleShiftInfoList = AtsScheduleShiftUtil.getScheduleShiftListByPriority(ctx,
+				personId, preDate, nextDate);
+		if (scheduleShiftInfoList != null && scheduleShiftInfoList.size() > 0) {
+			return scheduleShiftInfoList;
+		} else {
+			Map<String, AttendanceFileInfo> attendanceFiles = AtsScheduleShiftUtil.getAttendanceFileInfoByPersonIds(ctx,
+					personId, preDate, nextDate);
+			if (attendanceFiles != null && attendanceFiles.size() != 0) {
+				Map<String, AtsShiftInfo> atsShiftInfoMap = AtsScheduleShiftUtil
+						.getScheduleShiftListByAttendanceFile(ctx, attendanceFiles);
+				if (atsShiftInfoMap.size() == 0) {
+					return scheduleShiftInfoList;
+				} else {
+					Map<String, ScheduleShiftInfo> scheduleShiftByAtsShift = AtsScheduleShiftUtil
+							.getScheduleShiftByAtsShift(ctx, attendanceFiles, atsShiftInfoMap);
+					Iterator iterator = scheduleShiftByAtsShift.entrySet().iterator();
+
+					while (iterator.hasNext()) {
+						scheduleShiftInfoList.add( (ScheduleShiftInfo) ((Entry) iterator.next()).getValue());
+					}
+
+					return scheduleShiftInfoList;
+				}
+			} else {
+				return scheduleShiftInfoList;
+			}
+		}
+	}
+}