public int forcePunchLogProcess(PunchCardNeedParam logParam, string action, string from = "")
        {
            var thisWorkTime = logParam.thisWorkTime;
            var processLog   = logParam.punchCardLog;

            logParam.workDateTime     = workTimeProcess(thisWorkTime, processLog);
            processLog.lastOperaAccID = (int)loginID;

            if (action == "update")
            {
                processLog.updateTime = definePara.dtNow();
            }
            else
            {
                processLog.createTime = definePara.dtNow();
            }
            processLog.punchStatus = getStatusCode(logParam);
            int result = action == "update"? Repository.UpdatePunchCard(processLog, false) : Repository.AddPunchCardLog(processLog, false);

            if (result == 1)
            {
                calWorkTimeByID(processLog, thisWorkTime);
                if (processLog.punchStatus > psCode.normal && processLog.punchStatus != psCode.takeLeave)
                {
                    Repository.AddPunchLogWarnAndMessage(processLog);
                }
                if (action == "update" && from == "applySign")
                {
                    Repository.UpdatePunchLogWarn(processLog.ID);
                }
            }
            return(result);
        }
        //---------------------------------------------------------------------------------------
        public object getTodayPunchStatus()     //look my today PunchStatus
        {
            PunchCardNeedParam logParam = new PunchCardNeedParam();

            logParam.thisWorkTime = Repository.GetThisWorkTime((int)loginID);
            logParam.workDateTime = Repository.workTimeProcess(logParam.thisWorkTime);
            PunchCardLog[] dataLogArr = Repository.GetTodayPunchLog((int)loginID, logParam, 0);
            PunchCardLog   dataLog;

            if (dataLogArr[1] != null && dataLogArr[1].onlineTime.Year > 1)
            {
                dataLog = dataLogArr[1];
            }
            else if (dataLogArr[0] != null)
            {
                dataLog = dataLogArr[0];
            }
            else
            {
                dataLog = new PunchCardLog();
            }
            DateTime onlineDt  = dataLog.onlineTime;
            DateTime offlineDt = dataLog.offlineTime;

            return(rAjaxResult(
                       new {
                onlineTime = onlineDt.Year == 1? null : (object)onlineDt,
                offlineTime = offlineDt.Year == 1? null : (object)offlineDt,
            }
                       ));
        }
        public object addPunchCardLog(int action, int employeeID = 0)   //action 0:正常打卡/打下班卡 1:提早上班
        {
            if (employeeID == 0)
            {
                employeeID = (int)loginID;
            }
            var logParam = new PunchCardNeedParam();

            logParam.thisWorkTime = Repository.GetThisWorkTime(employeeID);
            logParam.workDateTime = Repository.workTimeProcess(logParam.thisWorkTime);
            PunchCardLog[] punchLogArr = Repository.GetTodayPunchLog(employeeID, logParam, action);
            logParam.punchCardLog = punchLogArr[0];
            if (punchLogArr[1] != null && punchLogArr[1].onlineTime.Year > 1)
            {
                //提前打卡後 將以該工作日為基礎
                logParam.workDateTime = Repository.workTimeProcess(logParam.thisWorkTime, punchLogArr[1]);
                logParam.punchCardLog = punchLogArr[1];
            }
            if (definePara.dtNow() >= logParam.workDateTime.ePunchDT)    //at ambiguous time
            {
                if (_session.GetInt32("againRequest") == null || _session.GetInt32("againRequest") == 0)
                {
                    _session.SetInt32("againRequest", 1);
                    var wt       = logParam.workDateTime;
                    var dtFormat = "yyyy/MM/dd HH:mm";
                    var offline  = wt.sWorkDt.ToString(dtFormat) + " ~ " + wt.eWorkDt.ToString(dtFormat);
                    var online   = wt.sWorkDt.AddDays(1).ToString(dtFormat) + " ~ " + wt.eWorkDt.AddDays(1).ToString(dtFormat);
                    return(new cusResult <dynamic> {
                        resCode = 1, result = 2, resultMsg = $"{offline}T{online}"
                    });
                }
                _session.SetInt32("againRequest", 0);
            }
            if (action == 1)
            {
                PunchCardLog newLogData = new PunchCardLog();
                if (punchLogArr[1] == null)
                {
                    newLogData.logDate = logParam.workDateTime.sWorkDt.Date.AddDays(1);
                }
                else
                {
                    newLogData.ID      = punchLogArr[1].ID;
                    newLogData.logDate = punchLogArr[1].logDate;
                }
                logParam.punchCardLog = newLogData;
            }
            var result = punchCardFn.punchCardProcess(logParam, action, employeeID);

            return(cudAjaxResult(result));
        }
        public object forceUpdatePunchCardLog(PunchCardLog updatePunchLog, string from)
        {
            if (updatePunchLog.ID == 0 || (updatePunchLog.onlineTime.Year == 1 && updatePunchLog.offlineTime.Year == 1))
            {
                return(cudAjaxResult(MessageCode.PunchCardDT_Illegal)); //此打卡時間紀錄不合法
            }
            updatePunchLog.accountID = Repository.GetThisLogAccID(updatePunchLog.ID);
            var logParam = new PunchCardNeedParam();

            logParam.punchCardLog = updatePunchLog;
            logParam.thisWorkTime = Repository.GetThisWorkTime(updatePunchLog.accountID);
            var result = punchCardFn.forcePunchLogProcess(logParam, "update", from);

            return(cudAjaxResult(result));
        }
        public object forceAddPunchCardLog(PunchCardLog newPunchLog)
        {
            if (newPunchLog.accountID == 0 ||
                (newPunchLog.onlineTime.Year == 1 && newPunchLog.offlineTime.Year == 1))
            {
                return(cudAjaxResult(MessageCode.PunchCardDT_Illegal)); //此打卡時間紀錄不合法
            }
            var logParam = new PunchCardNeedParam();

            logParam.punchCardLog = newPunchLog;
            logParam.thisWorkTime = Repository.GetThisWorkTime(newPunchLog.accountID);
            var result = punchCardFn.forcePunchLogProcess(logParam, "add");

            return(cudAjaxResult(result));
        }
Esempio n. 6
0
        private void punchCardProcess(int chkStatusDay)
        {
            List <PunchCardLog> warnLog = new List <PunchCardLog>();

            warnLog = Repository.GetAllPunchLogWithWarn(chkStatusDay);

            foreach (PunchCardLog log in warnLog)
            {
                PunchCardNeedParam logParam = new PunchCardNeedParam();
                logParam.punchCardLog = log;
                logParam.thisWorkTime = Repository.GetThisWorkTime(log.accountID);
                punchCardFn.processPunchlogWarn(logParam);
                //punchCardFn.processTakeLeaveWithLog(thisTakeLeave);
            }
        }
        public void processPunchlogWarn(PunchCardNeedParam logParam)    //排程用
        {
            PunchCardLog log = logParam.punchCardLog;
            WorkDateTime wt  = workTimeProcess(logParam.thisWorkTime, log);

            if (definePara.dtNow() < wt.ePunchDT)
            {
                return;
            }
            logParam.workDateTime = wt;
            log.punchStatus       = getStatusCode(logParam);
            log.lastOperaAccID    = 0;
            Repository.UpdatePunchCard(log, true);
            if (log.punchStatus > 1 && log.punchStatus != psCode.takeLeave)
            {
                Repository.AddPunchLogWarnAndMessage(log);
            }
        }
        public PunchCardLog[] GetTodayPunchLog(int employeeID, PunchCardNeedParam logParam, int action)
        {
            var wt    = logParam.workDateTime;
            var query = (from a in _DbContext.punchcardlogs
                         where a.accountID == employeeID &&
                         (
                             (a.logDate.Date == wt.sWorkDt.Date) ||
                             (a.onlineTime < wt.ePunchDT && a.onlineTime >= wt.sPunchDT) ||
                             (a.offlineTime <wt.ePunchDT && a.offlineTime> wt.sPunchDT)
                         )
                         select a).FirstOrDefault();
            var query2 = _DbContext.punchcardlogs.FirstOrDefault(   //尋找是否有提前打上班卡的紀錄或請假產生的紀錄
                b => b.accountID == employeeID &&
                b.logDate == wt.sWorkDt.Date.AddDays(1) && definePara.dtNow() >= wt.ePunchDT);

            return(new PunchCardLog[2] {
                query, query2
            });
        }
        //正常打卡
        public int punchCardProcess(PunchCardNeedParam logParam, int action, int employeeID)
        {
            WorkTimeRule thisWorkTime = logParam.thisWorkTime;
            PunchCardLog logData      = logParam.punchCardLog;
            WorkDateTime wt           = logParam.workDateTime;
            //需new一個出來 用原本的logData會等於context,一旦修改logData之後query後的context也會是修改後的(雖然沒儲存所以資料庫沒變)
            PunchCardLog newLogData;
            DateTime     dtNow       = definePara.dtNow();
            int          resultCount = 0; //0:操作異常 1:成功

            if (action == 1)              //action = 1 提早打上班卡
            {
                newLogData = new PunchCardLog()
                {
                    ID             = logData.ID,
                    accountID      = employeeID,
                    departmentID   = (int)loginDepartmentID,
                    logDate        = logData.logDate,
                    lastOperaAccID = (int)loginID,
                    onlineTime     = dtNow,
                    createTime     = dtNow
                };
            }
            else if (action == 0 && logData == null)    //action = 0  正常打卡或打下班卡
            //
            {
                newLogData = new PunchCardLog()
                {
                    accountID      = employeeID,
                    departmentID   = (int)loginDepartmentID,
                    logDate        = wt.sWorkDt.Date,
                    lastOperaAccID = (int)loginID,
                    createTime     = dtNow
                };
                if (dtNow >= wt.ePunchDT)    //在模糊區段 打下班卡
                {
                    newLogData.offlineTime = dtNow;
                }
                else    //非模糊區段 若上班卡沒打會先打上班卡 之後需要打一次下班卡
                {
                    newLogData.onlineTime = dtNow;
                }
            }
            else
            {
                newLogData                = new PunchCardLog();
                newLogData.ID             = logData.ID;
                newLogData.accountID      = logData.accountID;
                newLogData.departmentID   = logData.departmentID;
                newLogData.logDate        = logData.logDate;
                newLogData.onlineTime     = logData.onlineTime;
                newLogData.offlineTime    = logData.offlineTime;
                newLogData.punchStatus    = logData.punchStatus;
                newLogData.createTime     = logData.createTime;
                newLogData.lastOperaAccID = (int)loginID;
                newLogData.updateTime     = dtNow;
                if (dtNow >= wt.ePunchDT || logData.onlineTime.Year > 1)
                {
                    newLogData.offlineTime = dtNow;
                }
                else
                {
                    newLogData.onlineTime = dtNow;
                }
            }
            logParam.punchCardLog  = newLogData;
            logParam.workDateTime  = workTimeProcess(thisWorkTime, newLogData);
            newLogData.punchStatus = getStatusCode(logParam);
            resultCount            = newLogData.ID == 0? Repository.AddPunchCardLog(newLogData, true) : Repository.UpdatePunchCard(newLogData, true);
            if (resultCount == 1)     //一定要新增log成功 不然會沒logID
            {
                if (newLogData.punchStatus > psCode.normal && newLogData.punchStatus != psCode.takeLeave)
                {
                    Repository.AddPunchLogWarnAndMessage(newLogData);
                }
                else if (newLogData.punchStatus == psCode.normal)
                {
                    Repository.delPunchLogWarnAndMessage(newLogData);
                }
                if (action == 1)     //提早打上班卡 通知主管
                {
                    var accDetail = Repository.GetAccountDetail(newLogData.accountID);
                    var userName  = (string)accDetail.GetType().GetProperty("userName").GetValue(accDetail);
                    //obj.GetType().GetProperty(key).GetValue(obj);
                    Repository.systemSendMessage(userName, newLogData.accountID, "earlyPunch");
                }
            }
            return(resultCount);
        }
        public int getStatusCode(PunchCardNeedParam logParam, LeaveOfficeApply leave = null)
        {
            WorkDateTime wt          = logParam.workDateTime;
            PunchCardLog processLog  = logParam.punchCardLog;
            var          fullDayRest = false; //請整天假
            var          statusCode  = 0;     //statusCode:  0x01:正常 0x02:遲到 0x04:早退 0x08:加班 0x10:缺卡 0x20:曠職 0x40:請假

            if (wt.workAllTime)
            {
                return(psCode.normal);
            }
            var elasticityMin = wt.elasticityMin;   //彈性時間
            List <LeaveOfficeApply> thisLeave = new List <LeaveOfficeApply>();

            //if(leave == null){
            thisLeave = Repository.GetThisTakeLeave(processLog.accountID, wt.sWorkDt, wt.eWorkDt);
            //}else{
            //    thisLeave.Add(leave);
            //}
            if (thisLeave.Count > 0)
            {
                var allWorkLen = (wt.eWorkDt - wt.sWorkDt).TotalMinutes;
                var restLen    = (wt.eRestDt - wt.sRestDt).TotalMinutes;
                var workLen    = allWorkLen - restLen;
                var sum        = 0.0;
                foreach (var tmp in thisLeave)
                {
                    sum        += (tmp.endTime - tmp.startTime).TotalMinutes;
                    fullDayRest = (tmp.startTime <= wt.sWorkDt && tmp.endTime >= wt.eWorkDt)? true : false;
                }
                fullDayRest = sum >= workLen? true : fullDayRest;
                statusCode |= psCode.takeLeave;
            }

            if (processLog.onlineTime.Year == 1 && processLog.offlineTime.Year == 1)
            {
                if (definePara.dtNow() >= wt.ePunchDT)
                {
                    statusCode = fullDayRest? statusCode : (statusCode | psCode.noWork);
                }
                else
                {
                    if (definePara.dtNow() >= wt.eWorkDt)
                    {
                        statusCode = fullDayRest? statusCode : (statusCode | psCode.hadLost);
                    }
                }
            }
            else if (processLog.onlineTime.Year > 1 && processLog.offlineTime.Year > 1)
            {
                var newStartWt = wt.sWorkDt.AddMinutes(elasticityMin + 1);   //+1因遲到以時分為主 09:00:59 也不算遲到
                statusCode = processLog.onlineTime >= newStartWt? (statusCode | psCode.lateIn) : statusCode;
                var timeLen = (int)((processLog.onlineTime - wt.sWorkDt).TotalMinutes);
                timeLen    = (timeLen <0 || timeLen> elasticityMin)? 0: timeLen; //上班打卡超過彈性時間 下班就已下班時間為準
                statusCode = processLog.offlineTime < wt.eWorkDt.AddMinutes(timeLen)? (statusCode | psCode.earlyOut):statusCode;
                if (statusCode == psCode.takeLeave && (statusCode & psCode.lateIn) == 0 && (statusCode & psCode.earlyOut) == 0)
                {
                    statusCode = (statusCode | psCode.normal);
                }
            }
            else
            {
                if (processLog.onlineTime.Year > 1) //只有填上班
                {
                    var newStartWt = wt.sWorkDt.AddMinutes(elasticityMin + 1);
                    statusCode = processLog.onlineTime >= newStartWt? (statusCode | psCode.lateIn) : statusCode;
                    statusCode = definePara.dtNow() >= wt.ePunchDT ? (statusCode | psCode.hadLost) : statusCode; //打不到下班卡了
                }
                else                                                                                             //只有填下班
                {
                    statusCode |= psCode.hadLost;
                    statusCode  = processLog.offlineTime < wt.eWorkDt ? (statusCode | psCode.earlyOut) : statusCode;
                }
            }
            return(statusCode == 0? (psCode.normal) : statusCode);
        }
        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;
            }
            PunchCardNeedParam logParam = new PunchCardNeedParam();

            logParam.thisWorkTime = wtRule;
            do
            {
                var log = _DbContext.punchcardlogs.FirstOrDefault(b =>
                                                                  b.accountID == restLog.accountID && b.logDate == workDate);
                logParam.punchCardLog = log;
                if (log != null)
                {
                    log.lastOperaAccID    = restLog.lastOperaAccID;
                    log.updateTime        = definePara.dtNow();
                    logParam.workDateTime = punchCardFn.workTimeProcess(wtRule, log);
                    log.punchStatus       = punchCardFn.getStatusCode(logParam);
                    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(),
                        };
                        logParam.punchCardLog = newLog;
                        logParam.workDateTime = punchCardFn.workTimeProcess(wtRule, newLog);
                        newLog.punchStatus    = punchCardFn.getStatusCode(logParam, 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);
        }