public object getPunchLogByIDByDate(int employeeID, DateTime qDateStr)
        {
            if (employeeID == 0)
            {
                employeeID = (int)loginID;
            }

            WorkDateTime workTime = punchCardFn.workTimeProcess(Repository.GetThisWorkTime(employeeID), new PunchCardLog()
            {
                logDate = qDateStr
            });
            var sWorkDt  = workTime.sWorkDt;
            var eWorkDt  = workTime.eWorkDt;
            var punchLog = Repository.GetPunchLogByIDByDate(employeeID, qDateStr);
            List <LeaveOfficeApply> takeLeave = Repository.GetThisTakeLeave(employeeID, sWorkDt, eWorkDt);
            List <object>           leave     = new List <object>();

            foreach (var tmp in takeLeave)
            {
                var leaveName = aRepository.getApplyLeaveName(tmp.leaveID);
                leave.Add(new{ leaveName, tmp.startTime, tmp.endTime });
            }

            return(new{ punchLog = punchLog, takeLeave = leave });
        }
        public WorkDateTime workTimeProcess(WorkTimeRule thisWorkTime, PunchCardLog customLog = null)
        {
            var wt = new WorkDateTime();

            wt.sWorkDt  = definePara.dtNow().Date; //online work dateTime
            wt.eWorkDt  = definePara.dtNow().Date; //offline work dateTime
            wt.sPunchDT = definePara.dtNow().Date; //可打卡時間
            wt.ePunchDT = definePara.dtNow().Date; //
            var sRest_start = new TimeSpan(0);
            var eRest_sRest = new TimeSpan(0);

            if (customLog != null)
            {
                if (customLog.logDate.Year != 1)
                {
                    wt.sWorkDt = wt.eWorkDt = wt.sPunchDT = wt.ePunchDT = customLog.logDate.Date;
                }
                else if (customLog.onlineTime.Year != 1)
                {
                    wt.sWorkDt = wt.eWorkDt = wt.sPunchDT = wt.ePunchDT = customLog.onlineTime.Date;
                }
                else if (customLog.offlineTime.Year != 1)
                {
                    wt.sWorkDt = wt.eWorkDt = wt.sPunchDT = wt.ePunchDT = customLog.offlineTime.Date;
                }
            }
            if (thisWorkTime != null)
            {
                var eWork_sWork = thisWorkTime.endTime - thisWorkTime.startTime;
                eWork_sWork      = eWork_sWork.TotalSeconds < 0? eWork_sWork.Add(new TimeSpan(1, 0, 0, 0)) : eWork_sWork;
                wt.addEtHour     = (int)(24 * 60 + wt.lessStHour - eWork_sWork.TotalMinutes); //單位改為分鐘
                sRest_start      = thisWorkTime.sRestTime - thisWorkTime.startTime;
                sRest_start      = sRest_start.TotalSeconds < 0? sRest_start.Add(new TimeSpan(1, 0, 0, 0)) : sRest_start;
                eRest_sRest      = thisWorkTime.eRestTime - thisWorkTime.sRestTime;
                eRest_sRest      = eRest_sRest.TotalSeconds < 0? eRest_sRest.Add(new TimeSpan(1, 0, 0, 0)) : eRest_sRest;
                wt.type          = thisWorkTime.type;
                wt.workAllTime   = false;
                wt.sWorkDt       = wt.sWorkDt + thisWorkTime.startTime;
                wt.eWorkDt       = wt.eWorkDt + thisWorkTime.endTime;
                wt.eWorkDt       = wt.eWorkDt <= wt.sWorkDt ? wt.eWorkDt.AddDays(1) : wt.eWorkDt;
                wt.sPunchDT      = wt.sWorkDt.AddMinutes(wt.lessStHour);
                wt.ePunchDT      = wt.eWorkDt.AddMinutes(wt.addEtHour);
                wt.elasticityMin = thisWorkTime.elasticityMin;
                if (customLog == null)
                {
                    if (definePara.dtNow() >= wt.ePunchDT)
                    {
                        wt.sPunchDT = wt.sPunchDT.AddDays(1);
                        wt.ePunchDT = wt.ePunchDT.AddDays(1);
                        wt.sWorkDt  = wt.sPunchDT.AddMinutes((wt.lessStHour * -1));
                        wt.eWorkDt  = wt.ePunchDT.AddMinutes((wt.addEtHour * -1));
                    }
                    else if (definePara.dtNow() < wt.sPunchDT)
                    {
                        wt.sPunchDT = wt.sPunchDT.AddDays(-1);
                        wt.ePunchDT = wt.ePunchDT.AddDays(-1);
                        wt.sWorkDt  = wt.sPunchDT.AddMinutes((wt.lessStHour * -1));
                        wt.eWorkDt  = wt.ePunchDT.AddMinutes((wt.addEtHour * -1));
                    }
                }
            }
            else
            {
                wt.workAllTime = true;
                wt.eWorkDt     = wt.eWorkDt.AddDays(1);
                wt.ePunchDT    = wt.ePunchDT.AddDays(1);
            }
            wt.sRestDt = wt.sWorkDt.AddMinutes(sRest_start.TotalMinutes);
            wt.eRestDt = wt.sRestDt.AddMinutes(eRest_sRest.TotalMinutes);
            return(wt);
        }
        public bool chkApplyOvertimeData(OvertimeApply data)
        {
            var result   = true;
            var punchLog = _DbContext.punchcardlogs.FirstOrDefault(b => b.accountID == data.accountID && b.logDate == data.workDate);

            if (punchLog == null)
            {
                result = false;
            }
            else
            {
                result = punchLog.onlineTime.Year > 1 && punchLog.offlineTime.Year > 1? result : false;
            }
            //計算加班長度
            WorkTimeRule thisWorkTime = pRepository.GetThisWorkTime(data.accountID);
            PunchCardLog tmpLog       = new PunchCardLog()
            {
                logDate = data.workDate
            };
            WorkDateTime workTime       = punchCardFn.workTimeProcess(thisWorkTime, tmpLog);
            var          sRestTime      = thisWorkTime.sRestTime;
            var          eRestTime      = thisWorkTime.eRestTime;
            var          restTimeMinute = 0;
            var          restlength     = TimeSpan.Zero;

            if (eRestTime < sRestTime)
            {
                restlength = eRestTime.Add(new TimeSpan(24, 0, 0)) - sRestTime;
            }
            else
            {
                restlength = eRestTime - sRestTime;
            }
            restTimeMinute = (int)restlength.TotalMinutes;
            var st         = data.startDateTime;
            var et         = data.endDateTime;
            var overLength = 0; //加班長度

            if (st <= workTime.sRestDt && et >= workTime.eRestDt)
            {
                overLength = (int)((et - st).TotalMinutes) - restTimeMinute;
            }
            else if (st < workTime.sRestDt && et <= workTime.eRestDt)
            {
                if (et < workTime.sRestDt)
                {
                    overLength = (int)(et - st).TotalMinutes;
                }
                else
                {
                    overLength = (int)(workTime.sRestDt - st).TotalMinutes;
                }
            }
            else if (st >= workTime.sRestDt && et > workTime.eRestDt)
            {
                if (st > workTime.eRestDt)
                {
                    overLength = (int)(et - st).TotalMinutes;
                }
                else
                {
                    overLength = (int)(et - workTime.eRestDt).TotalMinutes;
                }
            }
            overLength      = (overLength / 30) * 30; //以半小時的倍數為準
            result          = overLength >= 30? result : false;
            data.timeLength = overLength;
            return(result);
        }
        public DateTime getLeaveEndTime(LeaveOfficeApply data)  //計算請假結束時間
        {
            var          workTime  = RepositoryPunch.GetThisWorkTime(data.accountID);
            WorkDateTime wdt       = punchCardFn.workTimeProcess(workTime);
            var          offsetDay = (data.startTime.Date - wdt.sWorkDt.Date).TotalDays;

            var workLengthMinute = (wdt.eWorkDt - wdt.sWorkDt).TotalMinutes;

            workLengthMinute = workLengthMinute < 0? workLengthMinute + 24 * 60 : workLengthMinute;
            var restLengthMinute = (wdt.eRestDt - wdt.sRestDt).TotalMinutes;

            restLengthMinute = restLengthMinute < 0? restLengthMinute + 24 * 60 : restLengthMinute;

            var useHalfVal    = data.unit == 3? Repository.IsUseHourHalfVal(data.leaveID) : false;
            var myDepartClass = (Repository.GetMyDepartClass(data.accountID)).Split(",");
            var totalMin      = 0.0;

            if (data.unit == 3) //小時
            {
                totalMin = data.unitVal * 60;
            }
            else if (data.unit == 2) //半天
            {
                data.startTime = wdt.sWorkDt.AddDays(offsetDay);
                totalMin       = (workLengthMinute - restLengthMinute) * 0.5; //半天時長
                if (data.unitVal == 2)                                        //1=上半天  2=下半天
                {
                    for (int i = 1; i <= totalMin; i++)
                    {
                        data.startTime = data.startTime.AddMinutes(1);
                        if (data.startTime.Hour == wdt.sRestDt.Hour && data.startTime.Minute == wdt.sRestDt.Minute)
                        {
                            data.startTime = data.startTime.AddMinutes(restLengthMinute);
                        }
                    }
                }
                data.unitVal = 1; //須改為1 一個半天
            }
            else                  //天
            {
                data.startTime = wdt.sWorkDt.AddDays(offsetDay);
                totalMin       = (workLengthMinute - restLengthMinute) * data.unitVal;
            }

            var eTime = data.startTime;
            var iTmp  = 1;

            for (; iTmp <= totalMin; iTmp++)
            {
                if (eTime.Hour == wdt.sRestDt.Hour && eTime.Minute == wdt.sRestDt.Minute)
                {
                    eTime = eTime.AddMinutes(restLengthMinute); //跳過休息時間
                }
                if (eTime.Hour == wdt.eWorkDt.Hour && eTime.Minute == wdt.eWorkDt.Minute)
                {
                    //若接下來時間超過下班時間 跳到隔天的上班時間繼續加
                    eTime = eTime.AddDays(1).AddMinutes(-workLengthMinute);
                    var flag = wdt.type == 1? false : true;                     //1:排休制(都要上班) 0:固定制
                    while (flag)                                                //判斷是否休假日 有就略過
                    {
                        var spDate = RepositoryPunch.GetThisSpecialDate(eTime); //是否有特殊日期
                        if (spDate == null)                                     //DayOfWeek.ToString("d") 轉換成星期幾
                        {
                            if ((eTime.DayOfWeek.ToString("d") == "0" || eTime.DayOfWeek.ToString("d") == "6"))
                            {
                                eTime = eTime.AddDays(1);
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                        else    //1:休假 2:上班
                        {
                            if ((spDate.status == 2 && Array.IndexOf(myDepartClass, spDate.departClass) > -1) ||
                                (spDate.status == 1 && Array.IndexOf(myDepartClass, spDate.departClass) == -1)
                                )
                            {
                                flag = false;
                            }
                            else
                            {
                                eTime = eTime.AddDays(1);
                            }
                        }
                    }
                }
                eTime = eTime.AddMinutes(1);
                if (eTime.Hour == wdt.eWorkDt.Hour && eTime.Minute == wdt.eWorkDt.Minute && data.unit == 3)
                {
                    break;
                }
            }//for(; iTmp<=totalMin; iTmp++)

            if (data.unit == 3)    //小時
            {
                if (iTmp < totalMin)    //若超過下班時間 以下班時間為底
                {
                    var hour = iTmp / 60;
                    //unitVal為實際請假時數(開始時間到下班時間)
                    data.unitVal = (float)(iTmp % 60 > 30? (++hour) : iTmp % 60 > 0? hour + 0.5 : hour);
                    data.note    = "note_overEndWorkTime"; //用此判斷是否有超過下班時間
                }
                if (useHalfVal)                            //可以有0.5小時
                {
                    var dot = data.unitVal - ((int)data.unitVal);
                    if (dot > 0)
                    {
                        dot          = (float)(dot > 0.5 ? 1 : 0.5);
                        data.unitVal = (int)data.unitVal + dot;
                    }
                }
                else
                {
                    data.unitVal = (float)(Math.Ceiling(data.unitVal)); //無條件進位
                }
            }
            return(eTime);
        }
        public WorkDateTime workTimeProcess(WorkTimeRule thisWorkTime, PunchCardLog customLog = null)
        {
            var wt    = new WorkDateTime();
            var dtNow = definePara.dtNow();

            wt.sWorkDt = dtNow.Date;  //online work dateTime
            wt.eWorkDt = dtNow.Date;  //offline work dateTime
            var eWork_sWork = new TimeSpan(0);
            var sRest_start = new TimeSpan(0);
            var eRest_sRest = new TimeSpan(0);

            if (customLog != null)
            {
                if (customLog.logDate.Year != 1)
                {
                    wt.sWorkDt = wt.eWorkDt = customLog.logDate.Date;
                }
                else if (customLog.onlineTime.Year != 1)
                {
                    wt.sWorkDt = wt.eWorkDt = customLog.onlineTime.Date;
                }
                else if (customLog.offlineTime.Year != 1)
                {
                    wt.sWorkDt = wt.eWorkDt = customLog.offlineTime.Date;
                }
            }
            if (thisWorkTime != null)
            {
                eWork_sWork = thisWorkTime.endTime - thisWorkTime.startTime;
                eWork_sWork = eWork_sWork.TotalSeconds < 0? eWork_sWork.Add(new TimeSpan(1, 0, 0, 0)) : eWork_sWork;
                // wt.addEtHour = (int)(24*60 + wt.lessStHour - eWork_sWork.TotalMinutes);   //單位改為分鐘
                sRest_start      = thisWorkTime.sRestTime - thisWorkTime.startTime;
                sRest_start      = sRest_start.TotalSeconds < 0? sRest_start.Add(new TimeSpan(1, 0, 0, 0)) : sRest_start;
                eRest_sRest      = thisWorkTime.eRestTime - thisWorkTime.sRestTime;
                eRest_sRest      = eRest_sRest.TotalSeconds < 0? eRest_sRest.Add(new TimeSpan(1, 0, 0, 0)) : eRest_sRest;
                wt.type          = thisWorkTime.type;
                wt.workAllTime   = false;
                wt.sWorkDt       = wt.sWorkDt + thisWorkTime.startTime;
                wt.eWorkDt       = wt.eWorkDt + thisWorkTime.endTime;
                wt.eWorkDt       = wt.eWorkDt <= wt.sWorkDt ? wt.eWorkDt.AddDays(1) : wt.eWorkDt;
                wt.sPunchDT      = wt.sWorkDt.AddMinutes(wt.lessStHour);
                wt.ePunchDT      = wt.eWorkDt.AddMinutes(wt.addEtHour);
                wt.elasticityMin = thisWorkTime.elasticityMin;
                if (customLog == null)
                {
                    if (dtNow < wt.sPunchDT && dtNow < wt.ePunchDT.AddDays(-1)) //2300-0800 0830打卡
                    {
                        wt.sWorkDt  = wt.sWorkDt.AddDays(-1);
                        wt.eWorkDt  = wt.eWorkDt.AddDays(-1);
                        wt.sPunchDT = wt.sWorkDt.AddMinutes(wt.lessStHour);
                        wt.ePunchDT = wt.eWorkDt.AddMinutes(wt.addEtHour);
                    }
                    else if (dtNow < wt.sPunchDT && dtNow >= wt.ePunchDT.AddDays(-1))
                    {
                        //ambiguous
                        //目前工作日判斷,把位於模糊區域的時間,以某工作日的加班來處理
                        wt.sWorkDt  = wt.sWorkDt.AddDays(-1);
                        wt.eWorkDt  = wt.eWorkDt.AddDays(-1);
                        wt.sPunchDT = wt.sWorkDt.AddMinutes(wt.lessStHour);
                        wt.ePunchDT = wt.eWorkDt.AddMinutes(wt.addEtHour);
                    }
                    else if (dtNow >= wt.ePunchDT && dtNow >= wt.sPunchDT.AddDays(1))   //0000-0800 2330打卡
                    {
                        wt.sWorkDt  = wt.sWorkDt.AddDays(1);
                        wt.eWorkDt  = wt.eWorkDt.AddDays(1);
                        wt.sPunchDT = wt.sWorkDt.AddMinutes(wt.lessStHour);
                        wt.ePunchDT = wt.eWorkDt.AddMinutes(wt.addEtHour);
                    }
                    else if (dtNow >= wt.ePunchDT && dtNow < wt.sPunchDT.AddDays(1))
                    {
                        //ambiguous
                        //目前工作日判斷,把位於模糊區域的時間,以某工作日的加班來處理
                        //不處理
                    }
                }
            }
            else
            {
                wt.workAllTime = true;
                wt.sPunchDT    = wt.sWorkDt;
                wt.eWorkDt     = wt.sWorkDt.AddDays(1);
                wt.ePunchDT    = wt.eWorkDt;
            }
            wt.sRestDt = wt.sWorkDt.AddMinutes(sRest_start.TotalMinutes);
            wt.eRestDt = wt.sRestDt.AddMinutes(eRest_sRest.TotalMinutes);
            return(wt);
        }
Beispiel #6
0
        public void punchLogWithTakeLeave(LeaveOfficeApply restLog)
        {
            var restST   = restLog.startTime;
            var restET   = restLog.endTime;
            var wtLength = 720;         //工作時間長度 unit:minute
            //因工作時間可能跨日 不能直接用restST.Date EX: 2300-0800 休下半天0400-0800
            var workDate = restST.Date; //工作天日期(logDate)
            var wtRule   = (from a in _DbContext.accounts
                            join b in _DbContext.worktimerules on a.timeRuleID equals b.ID
                            where a.ID == restLog.accountID
                            select b).FirstOrDefault();

            if (wtRule != null)
            {
                if (wtRule.endTime < wtRule.startTime)
                {
                    wtLength = (int)(wtRule.endTime.Add(new TimeSpan(24, 0, 0)) - wtRule.startTime).TotalMinutes;
                }
                else
                {
                    wtLength = (int)(wtRule.endTime - wtRule.startTime).TotalMinutes;
                }
                var restSTime = new TimeSpan(restST.Hour, restST.Minute, restST.Second);
                workDate = (wtRule.startTime > restSTime)? workDate.AddDays(-1) : workDate;
            }

            do
            {
                var log = _DbContext.punchcardlogs.FirstOrDefault(b =>
                                                                  b.accountID == restLog.accountID && b.logDate == workDate);
                if (log != null)
                {
                    log.lastOperaAccID = restLog.lastOperaAccID;
                    log.updateTime     = definePara.dtNow();
                    WorkDateTime wt = punchCardFn.workTimeProcess(wtRule, log);
                    log.punchStatus = punchCardFn.getStatusCode(wt, log);
                    if (restLog.applyStatus != 1)
                    {
                        if (wtRule != null)
                        {
                            var logEndTime = log.logDate + wtRule.endTime;
                            logEndTime = (wtRule.endTime <= wtRule.startTime)? logEndTime.AddDays(1) : logEndTime;
                            if (definePara.dtNow() <= logEndTime && log.onlineTime.Year == 1 && log.offlineTime.Year == 1)
                            {
                                _DbContext.Remove(log);
                            }
                        }
                        else
                        {
                            if (log.logDate > definePara.dtNow())
                            {
                                _DbContext.Remove(log);
                            }
                        }
                    }
                    _DbContext.SaveChanges();
                }
                else
                {
                    if (restLog.applyStatus == 1)
                    {
                        var          applyAcc = _DbContext.accounts.FirstOrDefault(b => b.ID == restLog.accountID);
                        var          departID = applyAcc == null? 0 : applyAcc.departmentID;
                        PunchCardLog newLog   = new PunchCardLog {
                            accountID = restLog.accountID, departmentID = departID,
                            logDate   = workDate, createTime = definePara.dtNow(),
                        };
                        WorkDateTime wt = punchCardFn.workTimeProcess(wtRule, newLog);
                        newLog.punchStatus = punchCardFn.getStatusCode(wt, newLog, restLog);
                        _DbContext.punchcardlogs.Add(newLog);
                        _DbContext.SaveChanges();
                    }
                }

                if (restST.AddMinutes(wtLength) < restET)
                {
                    restST   = restST.AddDays(1);
                    workDate = workDate.AddDays(1);
                }
                else
                {
                    restST = restST.AddMinutes(wtLength);
                }
            }while(restST < restET);
        }