feat: 품목정보 상세 패널 추가 및 프로젝트/근태/권한 기능 확장
- Items: 우측에 이미지, 담당자, 입고/발주내역 패널 추가 (fItems 윈폼 동일) - Project: 목록 및 상세 다이얼로그 구현 - Kuntae: 오류검사/수정 기능 추가 - UserAuth: 사용자 권한 관리 페이지 추가 - UserGroup: 그룹정보 다이얼로그로 전환 - Header: 사용자 메뉴 서브메뉴 방향 수정, 즐겨찾기 기능 - Backend API: Items 상세/담당자/구매내역, 근태 오류검사, 프로젝트 목록 등 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using FCOMMON;
|
||||
|
||||
@@ -11,6 +12,33 @@ namespace Project.Web
|
||||
{
|
||||
#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
|
||||
|
||||
/// <summary>
|
||||
/// 근태 목록 조회
|
||||
/// </summary>
|
||||
@@ -90,6 +118,350 @@ namespace Project.Web
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 근태 오류 검사 실행
|
||||
/// </summary>
|
||||
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<KuntaeErrorCheckResult>();
|
||||
var ngList = new List<KuntaeErrorCheckResult>();
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 날짜의 오류 검사
|
||||
/// </summary>
|
||||
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<string, double>();
|
||||
var cateListT = new Dictionary<string, double>();
|
||||
|
||||
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<string, double>();
|
||||
var dCRT = new Dictionary<string, double>();
|
||||
var dDRD = new Dictionary<string, double>();
|
||||
var dDRT = new Dictionary<string, double>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 근태 오류 수정 (재생성)
|
||||
/// </summary>
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 여러 날짜 오류 일괄 수정
|
||||
/// </summary>
|
||||
public string Kuntae_FixErrors(string dates)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dateList = JsonConvert.DeserializeObject<List<string>>(dates);
|
||||
var results = new List<object>();
|
||||
|
||||
foreach (var date in dateList)
|
||||
{
|
||||
var resultJson = Kuntae_FixError(date);
|
||||
var resultObj = JsonConvert.DeserializeObject<dynamic>(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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user