using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Script.Services; using System.Web.Services; using Wellan.Common; using Wellan.Data; using System.Data; using System.Net.Mail; using System.Text; using System.IO; /// /// BatchService 的摘要描述 /// [WebService(Namespace = "http://thinkyu.com/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class BatchService : System.Web.Services.WebService { public BatchService() { //如果使用設計的元件,請取消註解下列一行 //InitializeComponent(); } private WQuery SetupQuery() { var ConnectionConfigName = WConfig.GetConnectionConfigName(); WConnectionString.ConnectionConfigFile = WConfig.GetConnectionConfig(); var ConnectionString = WConnectionString.GetConnectionString(ConnectionConfigName); var ConnectionType = WConnectionString.GetConnectionType(ConnectionConfigName); var Query = new WQuery(ConnectionType, ConnectionString); WGuard1.SetQuery(ConnectionType, ConnectionString); return Query; } private void CheckPunchCard(DateTime date, ref List<打卡異常Item> employeeWarning, ref List<通知督導Item> supervisorWarning) { /* 差勤異常通知之定義及需求如下 一、差勤異常定義: 1.無上下班打卡紀錄,且無"出差" 或 "請假" 申請紀錄 2.出勤時數不足8小時(出勤時數指"打卡+出差+請假") 註:此處出差或請假申請只要申請人送單即可算 二、系統需求 1.差勤月報表:有異常者,於備註顯示 "出勤異常" 2.寄送異常通知:有出勤異常則於隔日通知個人,專案管理人統一於每月30日收到所有專案人員差勤異常通知 3.打卡限定:不能連續七日打卡 */ TimeCalc timeCalc = new TimeCalc(); var Query = SetupQuery(); var bhrdDao = new BhrdDAC(Query); var rparDao = new RparDAC(Query); var bsgpDao = new BsgpDAC(Query); var cmd1 = Query.NewCommand( @"SELECT A.BPENO, A.BPNME, A.BPEML, A.BPEM2, B.RCC01, B.RCC02, B.RCC07, B.RCC08 , C.RAPYN, D.BPPYM FROM BPSNView A LEFT JOIN RCRD B ON A.BPENO = B.RCUSR AND B.RCDAT = @DATE LEFT JOIN RASN C ON A.BPENO = C.RANUM AND (C.RAEDT IS NULL OR (C.RASDT <= @DATE AND C.RAEDT >= @DATE)) LEFT JOIN BPAA D ON C.RAPYN=D.BPPYN WHERE dbo.EmployeeOnboard(BPENO, @DATE) = 1 "); Query.AddParam(cmd1, "DATE", date); DataTable tableRcrd = Query.Select(cmd1); foreach (DataRow rowRcrd in tableRcrd.Rows) { var bpeno = WDAC.GetStringValue(rowRcrd["BPENO"]); // 員工編號 var bpnme = WDAC.GetStringValue(rowRcrd["BPNME"]); // 員工姓名 var bpeml = WDAC.GetStringValue(rowRcrd["BPEML"]); // 郵箱1 var bpem2 = WDAC.GetStringValue(rowRcrd["BPEM2"]); // 郵箱2 var rcc01 = WDAC.GetStringValue(rowRcrd["RCC01"]); // 上班打卡 var rcc02 = WDAC.GetStringValue(rowRcrd["RCC02"]); // 下班打卡 var rcc07 = WDAC.GetStringValue(rowRcrd["RCC07"]); // 外出打卡 var rcc08 = WDAC.GetStringValue(rowRcrd["RCC08"]); // 返回打卡 var isDuty = !bhrdDao.IsHoliday(bpeno, date); // 是否需上班 var rapyn = WDAC.GetStringValue(rowRcrd["RAPYN"]); // 派駐專案 var rapym = WDAC.GetStringValue(rowRcrd["BPPYM"]); // 派駐專案名稱 打卡檢查Item checkResult = rparDao.IsPunchcardNormal(date, bpeno, rapyn, isDuty, rcc01, rcc02, rcc07, rcc08); if (!checkResult.正常) { var supervisorItem = supervisorWarning.FirstOrDefault(x => x.專案年度號 == rapyn); if (supervisorItem == null) { supervisorItem = new 通知督導Item() { 專案年度號 = rapyn, 專案名稱 = rapym }; // 取得簽核人員第一關與第三關 // BSNME 姓名, BSEML 郵箱 var tableBsgp = bsgpDao.SelectByLevel(rapyn, "差勤", 1); foreach (DataRow rowBsgp in tableBsgp.Rows) { if (supervisorItem.督導List.Find(p => p.督導郵箱 == WDAC.GetStringValue(rowBsgp["BSEML"])) == null) { supervisorItem.督導List.Add(new 督導Item() { 督導姓名 = WDAC.GetStringValue(rowBsgp["BSNME"]), 督導郵箱 = WDAC.GetStringValue(rowBsgp["BSEML"]) }); } } tableBsgp = bsgpDao.SelectByLevel(rapyn, "差勤", 3); foreach (DataRow rowBsgp in tableBsgp.Rows) { if (supervisorItem.督導List.Find(p => p.督導郵箱 == WDAC.GetStringValue(rowBsgp["BSEML"])) == null) { supervisorItem.督導List.Add(new 督導Item() { 督導姓名 = WDAC.GetStringValue(rowBsgp["BSNME"]), 督導郵箱 = WDAC.GetStringValue(rowBsgp["BSEML"]) }); } } supervisorWarning.Add(supervisorItem); } var abnormalItem = new 打卡異常Item() { 員工編號 = bpeno, 姓名 = bpnme, 日期 = date, 郵箱_1 = bpeml, // 郵箱_2 = bpem2, 異常訊息 = checkResult.異常訊息 }; supervisorItem.異常List.Add(abnormalItem); employeeWarning.Add(abnormalItem); } } } private void CheckPunchCardMonth(DateTime month, ref List<打卡異常Item> employeeWarning, ref List<通知督導Item> supervisorWarning) { DateTime date = new DateTime(month.Year, month.Month, 1); DateTime endDate = date.AddMonths(1); DateTime today = DateTime.UtcNow.AddHours(8).Date; while (date < endDate && date < today) { CheckPunchCard(date, ref employeeWarning, ref supervisorWarning); date = date.AddDays(1); } } [WebMethod(EnableSession = true)] [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)] public GetDataResponse DoBatchJob(string apiKey, string jobName, string test) { WQuery Query = SetupQuery(); if (apiKey != "5D5F88D286A6479889B9DD986419A99C") { return new GetDataResponse() { Result = 400, Message = "Unauthorized" }; } var today = DateTime.UtcNow.AddHours(8).Date.AddDays(-1); List<打卡異常Item> employeeWarning = new List<打卡異常Item>(); List<通知督導Item> supervisorWarning = new List<通知督導Item>(); switch (jobName.ToUpper()) { case "CHECKPUNCHCARD": // 考勤檢查通知個人 CheckPunchCard(today, ref employeeWarning, ref supervisorWarning); // 發郵件給個人 foreach (var w in employeeWarning) { var d = String.Format("{0:yyyy-MM-dd}", w.日期); MailMessage mm = new MailMessage(); mm.Subject = String.Format("{0} 打卡異常通知", d); if (!string.IsNullOrEmpty(w.郵箱_1)) { mm.To.Add(new MailAddress(w.郵箱_1)); } else { continue; } mm.BodyEncoding = Encoding.UTF8; mm.IsBodyHtml = true; mm.Body = File.ReadAllText(HttpContext.Current.Server.MapPath("~/Template/出勤異常通知.html")) .Replace("{日期}", d) .Replace("{異常狀況}", w.異常訊息) ; // 發送郵件 try { Wellan.Service.WMailSender.GetInstance().Send( mm , string.Format("打卡異常通知 人員:{0} {1} 日期:{2} 異常:{3}", w.員工編號, w.姓名, d, w.異常訊息)); } catch { } } return new GetDataResponse() { Result = 0, // Data = Newtonsoft.Json.JsonConvert.SerializeObject(supervisorWarning) Data = "OK" }; case "CHECKPUNCHCARDMONTH": // 考勤檢查通知督導 if (today.AddDays(1).Day != 1 && string.Compare(test, "true") != 0) { return new GetDataResponse() { Result = 401, Data = "Not the end of month" }; } CheckPunchCardMonth(today, ref employeeWarning, ref supervisorWarning); byte[] UTF8BOM = new byte[] { 0xEF, 0xBB, 0xBF }; foreach (var w in supervisorWarning) { if (w.督導List == null || w.督導List.Count == 0) { continue; } MailMessage mm = new MailMessage(); mm.Subject = String.Format("{0:yyyy-MM} {1} {2} 專案打卡異常通知", today, w.專案年度號, w.專案名稱); foreach (var s in w.督導List) { if (!string.IsNullOrEmpty(s.督導郵箱)) { mm.To.Add(new MailAddress(s.督導郵箱)); } } mm.BodyEncoding = Encoding.UTF8; mm.IsBodyHtml = true; mm.Body = File.ReadAllText(HttpContext.Current.Server.MapPath("~/Template/出勤異常督導通知.html")) .Replace("{年月}", today.ToString("yyyy-MM")) .Replace("{專案編號}", w.專案年度號) .Replace("{專案名稱}", w.專案名稱) ; MemoryStream 出勤異常明細 = new MemoryStream(); 出勤異常明細.Write(UTF8BOM, 0, UTF8BOM.Length); byte[] b = Encoding.UTF8.GetBytes("\"日期\",\"員工編號\",\"姓名\",\"異常訊息\"\r\n"); 出勤異常明細.Write(b, 0, b.Length); foreach (var wp in w.異常List) { b = Encoding.UTF8.GetBytes(string.Format("\"{0:yyyy-MM-dd}\",=T(\"{1}\"),\"{2}\",\"{3}\"\r\n" , wp.日期, wp.員工編號, wp.姓名, wp.異常訊息)); 出勤異常明細.Write(b, 0, b.Length); } 出勤異常明細.Position = 0; mm.Attachments.Add(new Attachment(出勤異常明細, string.Format( "打卡異常_{0:yyyy-MM}_{1}_{2}.csv", today, w.專案年度號, w.專案名稱))); // 發送郵件 try { Wellan.Service.WMailSender.GetInstance().Send( mm , string.Format("{0:yyyy-MM} {1} {2} 專案打卡異常通知", today, w.專案年度號, w.專案名稱)); } catch { } } return new GetDataResponse() { Result = 0, // Data = Newtonsoft.Json.JsonConvert.SerializeObject(supervisorWarning) Data = "OK" }; default: return new GetDataResponse() { Result = 401, Message = "jobName required" }; } } } [Serializable] public class 打卡異常Item { public string 員工編號 { get; set; } public string 姓名 { get; set; } public DateTime 日期 { get; set; } public string 郵箱_1 { get; set; } public string 郵箱_2 { get; set; } public string 異常訊息 { get; set; } } public class 督導Item { public string 督導姓名 { get; set; } public string 督導郵箱 { get; set; } } public class 通知督導Item { public string 專案年度號 { get; set; } public string 專案名稱 { get; set; } public List<督導Item> 督導List { get; set; } public List<打卡異常Item> 異常List { get; set; } public 通知督導Item() { 督導List = new List<督導Item>(); 異常List = new List<打卡異常Item>(); } }