using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Text; using Newtonsoft.Json; using FCOMMON; namespace Project.Web { public partial class MachineBridge { #region Kuntae API #region 오류검사 관련 클래스 public class KuntaeErrorCheckResult { public string Date { get; set; } public string Gubun { get; set; } public string OccurDay { get; set; } public string OccurTime { get; set; } public string UseDay { get; set; } public string UseTime { get; set; } public string CateError { get; set; } public bool IsError { get; set; } public bool IsMagam { get; set; } } public class KuntaeErrorCheckProgress { public string CurrentDate { get; set; } public double JobreportOT { get; set; } public double HolidayRequestDay { get; set; } public double HolidayRequestTime { get; set; } public double KuntaeCRDay { get; set; } public double KuntaeCRTime { get; set; } public double KuntaeDRDay { get; set; } public double KuntaeDRTime { get; set; } } #endregion /// /// 근태 목록 조회 /// public string Kuntae_GetList(string sd, string ed) { try { var sql = @"SELECT k.*, u.name as userName FROM EETGW_Kuntae k WITH (nolock) LEFT JOIN Users u ON k.uid = u.id WHERE k.gcode = @gcode AND k.uid = @uid"; var parameters = new List(); parameters.Add(new SqlParameter("@gcode", info.Login.gcode)); parameters.Add(new SqlParameter("@uid", info.Login.no)); if (!string.IsNullOrEmpty(sd)) { sql += " AND k.kdate >= @sd"; parameters.Add(new SqlParameter("@sd", sd)); } if (!string.IsNullOrEmpty(ed)) { sql += " AND k.kdate <= @ed"; parameters.Add(new SqlParameter("@ed", ed)); } sql += " ORDER BY k.kdate DESC"; var cs = Properties.Settings.Default.gwcs; var cn = new SqlConnection(cs); var cmd = new SqlCommand(sql, cn); cmd.Parameters.AddRange(parameters.ToArray()); var da = new SqlDataAdapter(cmd); var dt = new DataTable(); da.Fill(dt); da.Dispose(); cmd.Dispose(); cn.Dispose(); return JsonConvert.SerializeObject(new { Success = true, Data = dt }, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 근태 삭제 /// public string Kuntae_Delete(int id) { try { var sql = "DELETE FROM EETGW_Kuntae WHERE idx = @idx AND gcode = @gcode AND uid = @uid"; var cs = Properties.Settings.Default.gwcs; var cn = new SqlConnection(cs); var cmd = new SqlCommand(sql, cn); cmd.Parameters.AddWithValue("@idx", id); cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); cmd.Parameters.AddWithValue("@uid", info.Login.no); cn.Open(); var result = cmd.ExecuteNonQuery(); cn.Close(); cmd.Dispose(); cn.Dispose(); return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "삭제되었습니다." : "삭제에 실패했습니다." }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 근태 오류 검사 실행 /// public string Kuntae_ErrorCheck(string sd, string ed) { try { var startDate = DateTime.Parse(sd); var endDate = DateTime.Parse(ed); var gcode = info.Login.gcode; var uid = info.Login.no; var okList = new List(); var ngList = new List(); var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) { cn.Open(); using (var cmd = new SqlCommand("", cn)) { cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = gcode; cmd.Parameters.Add("@uid", SqlDbType.VarChar).Value = uid; var idx = 0; while (true) { var currentDate = startDate.AddDays(idx++); if (currentDate > endDate) break; var pdate = currentDate.ToString("yyyy-MM-dd"); var result = CheckDateError(cmd, pdate, gcode); if (result.IsError) ngList.Add(result); else okList.Add(result); } } } return JsonConvert.SerializeObject(new { Success = true, OkList = okList, NgList = ngList }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 특정 날짜의 오류 검사 /// private KuntaeErrorCheckResult CheckDateError(SqlCommand cmd, string pdate, string gcode) { var result = new KuntaeErrorCheckResult { Date = pdate, Gubun = "입력/생성", IsError = false, IsMagam = false }; // 1. 업무일지 OT2 합계 (발생시간) cmd.CommandText = $"SELECT SUM(ISNULL(ot2,0)) FROM jobreport WHERE gcode = @gcode AND pdate='{pdate}' AND ISNULL(ot,0) > 0 AND ISNULL(ot2,0) > 0"; var jobreportOT = 0.0; var objJobreport = cmd.ExecuteScalar(); if (objJobreport != null && objJobreport != DBNull.Value) jobreportOT = Convert.ToDouble(objJobreport); // 2. 휴가신청 확인 (승인된 것만) cmd.CommandText = $"SELECT cate, SUM(HolyDays), SUM(HolyTimes) FROM EETGW_HolydayRequest WHERE gcode = @gcode AND sdate = '{pdate}' AND ISNULL(conf,0) = 1 GROUP BY cate"; var holidayDay = 0.0; var holidayTime = 0.0; var cateListD = new Dictionary(); var cateListT = new Dictionary(); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { var cate = reader[0].ToString(); var vDay = reader[1] != DBNull.Value ? Convert.ToDouble(reader[1]) : 0.0; var vTime = reader[2] != DBNull.Value ? Convert.ToDouble(reader[2]) : 0.0; holidayDay += vDay; holidayTime += vTime; if (vDay != 0.0) { if (cateListD.ContainsKey(cate)) cateListD[cate] += vDay; else cateListD.Add(cate, vDay); } if (vTime != 0.0) { if (cateListT.ContainsKey(cate)) cateListT[cate] += vTime; else cateListT.Add(cate, vTime); } } } // 3. 근태입력자료 확인 cmd.CommandText = $@"SELECT cate, SUM(term), SUM(crtime), SUM(termdr), SUM(drtime), SUM(drtimepms) FROM Holyday WHERE gcode = @gcode AND sdate = '{pdate}' AND ISNULL(extidx,-1) <> -1 GROUP BY cate"; var kuntaeCRDay = 0.0; var kuntaeCRTime = 0.0; var kuntaeDRDay = 0.0; var kuntaeDRTime = 0.0; var dCRD = new Dictionary(); var dCRT = new Dictionary(); var dDRD = new Dictionary(); var dDRT = new Dictionary(); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { var cate = reader[0].ToString(); var vCRD = reader[1] != DBNull.Value ? Convert.ToDouble(reader[1]) : 0.0; var vCRT = reader[2] != DBNull.Value ? Convert.ToDouble(reader[2]) : 0.0; var vDRD = reader[3] != DBNull.Value ? Convert.ToDouble(reader[3]) : 0.0; var vDRT = reader[4] != DBNull.Value ? Convert.ToDouble(reader[4]) : 0.0; if (vCRD != 0.0) { if (dCRD.ContainsKey(cate)) dCRD[cate] += vCRD; else dCRD.Add(cate, vCRD); } if (vCRT != 0.0) { if (dCRT.ContainsKey(cate)) dCRT[cate] += vCRT; else dCRT.Add(cate, vCRT); } if (vDRD != 0.0) { if (dDRD.ContainsKey(cate)) dDRD[cate] += vDRD; else dDRD.Add(cate, vDRD); } if (vDRT != 0.0) { if (dDRT.ContainsKey(cate)) dDRT[cate] += vDRT; else dDRT.Add(cate, vDRT); } kuntaeCRDay += vCRD; kuntaeCRTime += vCRT; kuntaeDRDay += vDRD; kuntaeDRTime += vDRT; } } // 4. 카테고리별 데이터 확인 var sbCate = new StringBuilder(); var cateErr = false; // 휴가신청(일) vs 근태입력(CR일) foreach (var item in cateListD) { if (!dCRD.ContainsKey(item.Key)) { sbCate.Append($"{item.Key}(X)"); cateErr = true; break; } else if (dCRD[item.Key] != item.Value) { sbCate.Append($"{item.Key}({dCRD[item.Key]}|{item.Value})"); cateErr = true; break; } } if (!cateErr) { foreach (var item in cateListT) { if (!dCRT.ContainsKey(item.Key)) { sbCate.Append($"{item.Key}(X)"); cateErr = true; break; } else if (dCRT[item.Key] != item.Value) { sbCate.Append($"{item.Key}({dCRT[item.Key]}|{item.Value})"); cateErr = true; break; } } } if (!cateErr) { foreach (var item in dCRD) { if (item.Key.Equals("대체")) continue; if (!cateListD.ContainsKey(item.Key)) { sbCate.Append($"{item.Key}(X)"); cateErr = true; break; } else if (cateListD[item.Key] != item.Value) { sbCate.Append($"{item.Key}({cateListD[item.Key]}|{item.Value})"); cateErr = true; break; } } } if (!cateErr) { foreach (var item in dCRT) { if (item.Key.Equals("대체")) continue; if (!cateListT.ContainsKey(item.Key)) { sbCate.Append($"{item.Key}(X)"); cateErr = true; break; } else if (cateListT[item.Key] != item.Value) { sbCate.Append($"{item.Key}({cateListT[item.Key]}|{item.Value})"); cateErr = true; break; } } } // 5. 결과 생성 result.OccurDay = $"--/{kuntaeDRDay}"; result.OccurTime = $"{jobreportOT}/{kuntaeDRTime}"; result.UseDay = $"{holidayDay}/{kuntaeCRDay}"; result.UseTime = $"{holidayTime}/{kuntaeCRTime}"; result.CateError = sbCate.ToString(); // 오류 여부 판단 if (jobreportOT != kuntaeDRTime) result.IsError = true; if (holidayDay != kuntaeCRDay) result.IsError = true; if (holidayTime != kuntaeCRTime) result.IsError = true; if (cateErr) result.IsError = true; // 마감 여부 확인 if (result.IsError) { result.IsMagam = DBM.GetMagamStatus(pdate.Substring(0, 7)); } return result; } /// /// 근태 오류 수정 (재생성) /// public string Kuntae_FixError(string pdate) { try { var gcode = info.Login.gcode; var uid = info.Login.no; var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) { cn.Open(); using (var cmd = new SqlCommand("", cn)) { cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = gcode; cmd.Parameters.Add("@uid", SqlDbType.VarChar).Value = uid; cmd.Parameters.Add("@pdate", SqlDbType.VarChar).Value = pdate; // 1. 근태-업무일지자료 삭제 cmd.CommandText = "DELETE FROM Holyday WHERE gcode = @gcode AND extcate = 'HO' AND sdate = @pdate AND ISNULL(extidx,-1) <> -1"; var cnt1 = cmd.ExecuteNonQuery(); // 2. 근태-업무일지자료 생성 cmd.CommandText = @"INSERT INTO Holyday(gcode, cate, sdate, edate, term, crtime, termdr, DrTime, contents, [uid], wdate, wuid, extcate, extidx) SELECT gcode, '대체', pdate, pdate, 0, 0, 0, ISNULL(ot2,0), projectname, uid, GETDATE(), @uid + '-ERR', 'HO', idx FROM jobreport WHERE gcode = @gcode AND pdate = @pdate AND ISNULL(ot2,0) > 0 AND ISNULL(ot,0) > 0"; var cnt2 = cmd.ExecuteNonQuery(); // 3. 근태-휴가신청자료 삭제 cmd.CommandText = "DELETE FROM Holyday WHERE gcode = @gcode AND extcate = '휴가' AND sdate = @pdate AND ISNULL(extidx,-1) <> -1"; var cnt3 = cmd.ExecuteNonQuery(); // 4. 근태-휴가신청자료 생성 (승인완료된 자료 대상) cmd.CommandText = @"INSERT INTO Holyday(gcode, cate, sdate, edate, term, crtime, termdr, DrTime, contents, [uid], wdate, wuid, extcate, extidx) SELECT gcode, cate, sdate, edate, ISNULL(holydays,0), ISNULL(holytimes,0), 0, 0, HolyReason, uid, GETDATE(), @uid + '-ERR', '휴가', idx FROM EETGW_HolydayRequest WHERE gcode = @gcode AND sdate = @pdate AND ISNULL(conf,0) = 1"; var cnt4 = cmd.ExecuteNonQuery(); return JsonConvert.SerializeObject(new { Success = true, Message = $"{pdate} 재생성 완료 (삭제: {cnt1 + cnt3}건, 생성: {cnt2 + cnt4}건)" }); } } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 여러 날짜 오류 일괄 수정 /// public string Kuntae_FixErrors(string dates) { try { var dateList = JsonConvert.DeserializeObject>(dates); var results = new List(); foreach (var date in dateList) { var resultJson = Kuntae_FixError(date); var resultObj = JsonConvert.DeserializeObject(resultJson); results.Add(new { Date = date, Success = (bool)resultObj.Success, Message = (string)resultObj.Message }); } return JsonConvert.SerializeObject(new { Success = true, Results = results }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } #endregion } }