using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using Newtonsoft.Json; using FCOMMON; namespace Project.Web { public partial class MachineBridge { #region Project API /// /// 프로젝트 목록 조회 /// public string Project_GetProjects(string status, string userFilter) { try { var sql = @"SELECT * FROM EETGW_Project WITH (nolock) WHERE gcode = @gcode"; var parameters = new List(); parameters.Add(new SqlParameter("@gcode", info.Login.gcode)); if (!string.IsNullOrEmpty(status)) { sql += " AND 상태 = @status"; parameters.Add(new SqlParameter("@status", status)); } if (userFilter == "my") { sql += " AND (프로젝트관리자 LIKE @userName OR 설계담당 LIKE @userName OR 전장담당 LIKE @userName OR 프로그램담당 LIKE @userName)"; parameters.Add(new SqlParameter("@userName", "%" + info.Login.nameK + "%")); } sql += " ORDER BY 시작일 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, CurrentUser = info.Login.nameK }, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 상세 조회 /// public string Project_GetProject(int id) { try { var sql = "SELECT * FROM EETGW_Project WHERE idx = @idx AND gcode = @gcode"; 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); var da = new SqlDataAdapter(cmd); var dt = new DataTable(); da.Fill(dt); da.Dispose(); cmd.Dispose(); cn.Dispose(); if (dt.Rows.Count > 0) { return JsonConvert.SerializeObject(new { Success = true, Data = dt.Rows[0] }, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } return JsonConvert.SerializeObject(new { Success = false, Message = "프로젝트를 찾을 수 없습니다." }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 생성 /// public string Project_CreateProject(string name, string process, string sdate, string edate, string ddate, string odate, string userManager, string status, string memo) { try { var sql = @"INSERT INTO EETGW_Project (gcode, 프로젝트명, 프로젝트공정, 시작일, 완료일, 만료일, 출고일, 프로젝트관리자, 상태, memo, wuid, wdate) VALUES (@gcode, @name, @process, @sdate, @edate, @ddate, @odate, @userManager, @status, @memo, @wuid, GETDATE()); SELECT SCOPE_IDENTITY();"; var cs = Properties.Settings.Default.gwcs; var cn = new SqlConnection(cs); var cmd = new SqlCommand(sql, cn); cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); cmd.Parameters.AddWithValue("@name", name ?? ""); cmd.Parameters.AddWithValue("@process", process ?? ""); cmd.Parameters.AddWithValue("@sdate", string.IsNullOrEmpty(sdate) ? (object)DBNull.Value : sdate); cmd.Parameters.AddWithValue("@edate", string.IsNullOrEmpty(edate) ? (object)DBNull.Value : edate); cmd.Parameters.AddWithValue("@ddate", string.IsNullOrEmpty(ddate) ? (object)DBNull.Value : ddate); cmd.Parameters.AddWithValue("@odate", string.IsNullOrEmpty(odate) ? (object)DBNull.Value : odate); cmd.Parameters.AddWithValue("@userManager", userManager ?? ""); cmd.Parameters.AddWithValue("@status", status ?? "진행"); cmd.Parameters.AddWithValue("@memo", memo ?? ""); cmd.Parameters.AddWithValue("@wuid", info.Login.no); cn.Open(); var newId = Convert.ToInt32(cmd.ExecuteScalar()); cn.Close(); cmd.Dispose(); cn.Dispose(); return JsonConvert.SerializeObject(new { Success = true, Message = "프로젝트가 생성되었습니다.", Data = new { idx = newId } }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 수정 /// public string Project_UpdateProject(int idx, string name, string process, string sdate, string edate, string ddate, string odate, string userManager, string status, string memo) { try { var sql = @"UPDATE EETGW_Project SET 프로젝트명 = @name, 프로젝트공정 = @process, 시작일 = @sdate, 완료일 = @edate, 만료일 = @ddate, 출고일 = @odate, 프로젝트관리자 = @userManager, 상태 = @status, memo = @memo, wuid = @wuid, wdate = GETDATE() WHERE idx = @idx AND gcode = @gcode"; var cs = Properties.Settings.Default.gwcs; var cn = new SqlConnection(cs); var cmd = new SqlCommand(sql, cn); cmd.Parameters.AddWithValue("@idx", idx); cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); cmd.Parameters.AddWithValue("@name", name ?? ""); cmd.Parameters.AddWithValue("@process", process ?? ""); cmd.Parameters.AddWithValue("@sdate", string.IsNullOrEmpty(sdate) ? (object)DBNull.Value : sdate); cmd.Parameters.AddWithValue("@edate", string.IsNullOrEmpty(edate) ? (object)DBNull.Value : edate); cmd.Parameters.AddWithValue("@ddate", string.IsNullOrEmpty(ddate) ? (object)DBNull.Value : ddate); cmd.Parameters.AddWithValue("@odate", string.IsNullOrEmpty(odate) ? (object)DBNull.Value : odate); cmd.Parameters.AddWithValue("@userManager", userManager ?? ""); cmd.Parameters.AddWithValue("@status", status ?? "진행"); cmd.Parameters.AddWithValue("@memo", memo ?? ""); cmd.Parameters.AddWithValue("@wuid", 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 Project_DeleteProject(int id) { try { var sql = "DELETE FROM EETGW_Project WHERE idx = @idx AND gcode = @gcode"; 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); 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 }); } } #endregion #region Project Search API (업무일지용) /// /// 업무일지용 프로젝트 검색 (Projects 테이블 + 과거 업무일지 항목명) /// public string Project_Search(string keyword) { try { var cs = Properties.Settings.Default.gwcs; var result = new List(); // 1. Projects 테이블에서 검색 var sqlProjects = @"SELECT idx, name, ISNULL(userManager,'') as userManager, ISNULL(userMain,'') as userMain, ISNULL(status,'') as status FROM Projects WITH (nolock) WHERE gcode = @gcode AND (name LIKE @keyword OR CAST(idx AS VARCHAR) LIKE @keyword) AND status NOT IN ('보류', '취소') ORDER BY CASE WHEN status = '진행' THEN 1 WHEN status = '준비' THEN 2 WHEN status = '완료(보고)' THEN 3 ELSE 4 END, pdate DESC, name"; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sqlProjects, cn)) { cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); cmd.Parameters.AddWithValue("@keyword", "%" + (keyword ?? "") + "%"); using (var da = new SqlDataAdapter(cmd)) { var dt = new DataTable(); da.Fill(dt); foreach (DataRow row in dt.Rows) { result.Add(new { idx = Convert.ToInt32(row["idx"]), name = row["name"]?.ToString() ?? "", userManager = row["userManager"]?.ToString() ?? "", userMain = row["userMain"]?.ToString() ?? "", status = row["status"]?.ToString() ?? "", source = "project" }); } } } // 2. 과거 업무일지 항목명에서 검색 (프로젝트에 없는 항목들) var sqlJobItems = @"SELECT TOP 50 MAX(pdate) as lastDate, projectName, ISNULL(MAX(pidx), -1) as pidx FROM JobReport WITH (nolock) WHERE gcode = @gcode AND projectName LIKE @keyword AND projectName IS NOT NULL AND projectName <> '' GROUP BY projectName ORDER BY MAX(pdate) DESC"; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sqlJobItems, cn)) { cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); cmd.Parameters.AddWithValue("@keyword", "%" + (keyword ?? "") + "%"); using (var da = new SqlDataAdapter(cmd)) { var dt = new DataTable(); da.Fill(dt); foreach (DataRow row in dt.Rows) { var pidx = row["pidx"] != DBNull.Value ? Convert.ToInt32(row["pidx"]) : -1; var projectName = row["projectName"]?.ToString() ?? ""; // 이미 Projects에서 가져온 항목과 중복 체크 if (!result.Exists(r => ((dynamic)r).name == projectName)) { result.Add(new { idx = pidx, name = projectName, userManager = "", userMain = "", status = "", source = "jobreport", lastDate = row["lastDate"] != DBNull.Value ? Convert.ToDateTime(row["lastDate"]).ToString("yyyy-MM-dd") : "" }); } } } } return JsonConvert.SerializeObject(new { Success = true, Data = result }); } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 현재 사용자의 프로젝트 목록 (업무일지 콤보박스용) /// public string Project_GetUserProjects() { try { var cs = Properties.Settings.Default.gwcs; var userName = info.Login.no; var sql = @"SELECT idx, name, ISNULL(status,'') as status FROM Projects WITH (nolock) WHERE gcode = @gcode AND (ISNULL(userManager,'') LIKE @userName OR ISNULL(userMain,'') LIKE @userName OR ISNULL(usersub,'') LIKE @userName) AND status NOT IN ('보류', '취소', '완료(보고)') ORDER BY status DESC, pdate DESC, name"; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sql, cn)) { cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); cmd.Parameters.AddWithValue("@userName", "%" + userName + "%"); using (var da = new SqlDataAdapter(cmd)) { var dt = new DataTable(); da.Fill(dt); return JsonConvert.SerializeObject(new { Success = true, Data = dt }); } } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } #endregion #region Project List API (fProjectList 화면용) /// /// 프로젝트 분류(category) 목록 조회 /// public string Project_GetCategories() { try { var sql = @"SELECT category FROM projects WITH (nolock) WHERE gcode = @gcode AND ISNULL(category,'') <> '' GROUP BY category ORDER BY category"; var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sql, cn)) { cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); var result = new List { "--전체--" }; cn.Open(); using (var rdr = cmd.ExecuteReader()) { while (rdr.Read()) { result.Add(rdr[0]?.ToString() ?? ""); } } return JsonConvert.SerializeObject(new { Success = true, Data = result }); } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 공정(userprocess) 목록 조회 /// public string Project_GetProcesses() { try { var sql = @"SELECT userprocess FROM projects WITH (nolock) WHERE gcode = @gcode AND ISNULL(userprocess,'') <> '' GROUP BY userprocess ORDER BY userprocess"; var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sql, cn)) { cmd.Parameters.AddWithValue("@gcode", info.Login.gcode); var result = new List { "전체" }; cn.Open(); using (var rdr = cmd.ExecuteReader()) { while (rdr.Read()) { result.Add(rdr[0]?.ToString() ?? ""); } } return JsonConvert.SerializeObject(new { Success = true, Data = result }); } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 목록 조회 (fProjectList 화면용) /// public string Project_GetList(string statusFilter, string category, string process, string userFilter, string yearStart, string yearEnd, string dateType) { try { var sql = @"SELECT idx, pidx, status, asset, [level], rev, [process], part, pdate, [name], userManager, usermain, usersub, userhw2, reqstaff, costo, costn, cnt, remark_req, remark_ans, sdate, ddate, edate, odate, progress, bmajoritem, memo, wuid, wdate, orderno, crdue, import, [path], userprocess, bCost, bFanOut, bHighlight, div, model, serial, championid, designid, epanelid, softwareid, effect_tangible, effect_intangible, dbo.getUserName2(championid, usermanager) as name_champion, dbo.getUserName2(designid, usermain) as name_design, dbo.getUserName2(epanelid, userhw2) as name_epanel, dbo.getUserName2(softwareid, usersub) as name_software, category, ReqLine, ReqSite, ReqPackage, ReqPlant, pno, kdate, jasmin, sfi, (SELECT MAX(pdate) FROM ProjectsHistory WHERE pidx = Projects.idx) as lasthistory_date, dbo.getLastProjectScheduleNo(gcode, idx) as lastSchNo, cramount, panelimage, Priority, sfi_count, dbo.getScheduleProgress(idx) as ProgressPrj, dbo.getProjectFinishRate(gcode, idx) AS finishrate FROM Projects WITH (nolock) WHERE gcode = @gcode AND ISNULL(div,'') <> 'EB' AND ISNULL(isdel,0) = 0"; var parameters = new List(); parameters.Add(new SqlParameter("@gcode", info.Login.gcode)); // 상태 필터 if (!string.IsNullOrEmpty(statusFilter) && statusFilter != "all") { var statuses = statusFilter.Split(','); var statusParams = new List(); for (int i = 0; i < statuses.Length; i++) { var paramName = "@status" + i; statusParams.Add(paramName); parameters.Add(new SqlParameter(paramName, statuses[i].Trim())); } sql += " AND status IN (" + string.Join(",", statusParams) + ")"; } // 분류 필터 if (!string.IsNullOrEmpty(category) && category != "--전체--") { sql += " AND ISNULL(category,'') LIKE @category"; parameters.Add(new SqlParameter("@category", category + "%")); } // 공정 필터 if (!string.IsNullOrEmpty(process) && process != "전체") { sql += " AND ISNULL(userprocess,'') = @process"; parameters.Add(new SqlParameter("@process", process)); } // 사용자 필터 if (!string.IsNullOrEmpty(userFilter)) { sql += @" AND (ISNULL(userManager,'') LIKE @userFilter OR ISNULL(usermain,'') LIKE @userFilter OR ISNULL(reqstaff,'') LIKE @userFilter OR ISNULL(usersub,'') LIKE @userFilter OR dbo.getUserName(championid) LIKE @userFilter OR dbo.getUserName(designid) LIKE @userFilter OR dbo.getUserName(epanelid) LIKE @userFilter OR dbo.getUserName(softwareid) LIKE @userFilter)"; parameters.Add(new SqlParameter("@userFilter", "%" + userFilter + "%")); } // 날짜 필터 if (!string.IsNullOrEmpty(dateType) && dateType != "0" && !string.IsNullOrEmpty(yearStart)) { string dateField = "sdate"; switch (dateType) { case "1": dateField = "sdate"; break; case "2": dateField = "ddate"; break; case "3": dateField = "edate"; break; case "4": dateField = "odate"; break; } sql += $" AND {dateField} BETWEEN @dateStart AND @dateEnd"; parameters.Add(new SqlParameter("@dateStart", yearStart + "-01-01")); parameters.Add(new SqlParameter("@dateEnd", (string.IsNullOrEmpty(yearEnd) ? yearStart : yearEnd) + "-12-31")); } // 정렬 sql += @" ORDER BY (CASE WHEN status = '진행' THEN '0' WHEN status = '검토' THEN '1' WHEN status = '대기' THEN '2' WHEN status = '완료' THEN '3' WHEN status = '완료(보고)' THEN '4' WHEN status = '보류' THEN '5' WHEN status = '취소' THEN '9' ELSE '5' END), userManager, sdate"; var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sql, cn)) { cmd.Parameters.AddRange(parameters.ToArray()); using (var da = new SqlDataAdapter(cmd)) { var dt = new DataTable(); da.Fill(dt); // 상태별 건수 집계 var statusCounts = new Dictionary { { "검토", 0 }, { "진행", 0 }, { "대기", 0 }, { "보류", 0 }, { "완료", 0 }, { "완료(보고)", 0 }, { "취소", 0 } }; decimal sumCosto = 0, sumCostn = 0; foreach (DataRow row in dt.Rows) { var st = row["status"]?.ToString() ?? ""; if (statusCounts.ContainsKey(st)) statusCounts[st]++; if (row["costo"] != DBNull.Value) sumCosto += Convert.ToDecimal(row["costo"]); if (row["costn"] != DBNull.Value) sumCostn += Convert.ToDecimal(row["costn"]); } return JsonConvert.SerializeObject(new { Success = true, Data = dt, StatusCounts = statusCounts, TotalCosto = sumCosto, TotalCostn = sumCostn, CurrentUser = info.Login.nameK }, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 히스토리 조회 /// public string Project_GetHistory(int projectIdx) { try { var sql = @"SELECT idx, pidx, pdate, progress, remark, wuid, wdate, dbo.getUserName(wuid) as wname FROM ProjectsHistory WITH (nolock) WHERE pidx = @pidx ORDER BY pdate DESC, idx DESC"; var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sql, cn)) { cmd.Parameters.AddWithValue("@pidx", projectIdx); using (var da = new SqlDataAdapter(cmd)) { var dt = new DataTable(); da.Fill(dt); return JsonConvert.SerializeObject(new { Success = true, Data = dt }); } } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 히스토리 저장 /// public string Project_SaveHistory(int idx, int pidx, string pdate, int progress, string remark) { try { var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) { cn.Open(); string sql; if (idx > 0) { // 수정 sql = @"UPDATE ProjectsHistory SET remark = @remark, progress = @progress, wdate = GETDATE(), wuid = @wuid WHERE idx = @idx"; } else { // 신규 등록 sql = @"INSERT INTO ProjectsHistory (pidx, pdate, progress, remark, wuid, wdate) VALUES (@pidx, @pdate, @progress, @remark, @wuid, GETDATE())"; } using (var cmd = new SqlCommand(sql, cn)) { if (idx > 0) { cmd.Parameters.AddWithValue("@idx", idx); } cmd.Parameters.AddWithValue("@pidx", pidx); cmd.Parameters.AddWithValue("@pdate", pdate); cmd.Parameters.AddWithValue("@progress", progress); cmd.Parameters.AddWithValue("@remark", remark ?? ""); cmd.Parameters.AddWithValue("@wuid", info.Login.no); int affected = cmd.ExecuteNonQuery(); if (affected > 0) { return JsonConvert.SerializeObject(new { Success = true, Message = "저장되었습니다." }); } else { return JsonConvert.SerializeObject(new { Success = false, Message = "저장에 실패했습니다." }); } } } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } /// /// 프로젝트 일일 메모 조회 /// public string Project_GetDailyMemo(int projectIdx) { try { var sql = @"SELECT idx, pidx, pdate, remark, wuid, wdate, dbo.getUserName(wuid) as wname FROM EETGW_ProjecthistoryD WITH (nolock) WHERE pidx = @pidx ORDER BY pdate DESC, idx DESC"; var cs = Properties.Settings.Default.gwcs; using (var cn = new SqlConnection(cs)) using (var cmd = new SqlCommand(sql, cn)) { cmd.Parameters.AddWithValue("@pidx", projectIdx); using (var da = new SqlDataAdapter(cmd)) { var dt = new DataTable(); da.Fill(dt); return JsonConvert.SerializeObject(new { Success = true, Data = dt }); } } } catch (Exception ex) { return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } #endregion } }