1. 업무일지 작업형태 선택 ui 변경

2. 작업형태 목록 편집 UI 추가
3. 스케쥴 관련메일 발송주기를 15분에서 30분으로 변경하고 18시 이후에는 발송하지 않게 한다(최근 오류메세지가 수신된다)
This commit is contained in:
chi
2025-01-03 09:09:25 +09:00
parent c810348fa6
commit 4593c6fd74
25 changed files with 1644 additions and 664 deletions

View File

@@ -32,6 +32,11 @@ namespace FPJ0000.JobReport_
this.FullName = fullname;
this.dsJobReport.Common.TableNewRow += Common_TableNewRow;
this.FormClosing += FJobProcessManager_FormClosing;
this.KeyPreview = true;
this.KeyDown += (s1, e1) => {
if (e1.KeyCode == Keys.Escape) this.Close();
};
// 이벤트 핸들러 연결
treeView1.ItemDrag += TreeView1_ItemDrag;
@@ -47,8 +52,17 @@ namespace FPJ0000.JobReport_
lbWarningManager.Visible = isAdmin;
lbWarningUser.Visible = !isAdmin;
btSelect.Visible = !isAdmin;
if (fullname.isEmpty() == false)
{
this.Text = $"작업형태 선택(기존값:{fullname})";
var buf = fullname.Split('|');
var prc = buf[0].Trim();
this.tbProcessE.Text = prc;
this.tbProcessI.Text = prc;
this.tbProcessI.Enabled = false;
this.tbProcessE.Enabled = false;
}
}
private void TreeView1_ItemDrag(object sender, ItemDragEventArgs e)
@@ -78,6 +92,11 @@ namespace FPJ0000.JobReport_
private void TreeView1_DragDrop(object sender, DragEventArgs e)
{
if (this.bn.Enabled == false)
{
AR.UTIL.MsgE("권한이 없어 drag & drop 을 사용할 수 없습니다");
return;
}
if (IsAdmin == false) return;
// 드롭된 위치의 노드 찾기
Point pt = treeView1.PointToClient(new Point(e.X, e.Y));
@@ -120,12 +139,16 @@ namespace FPJ0000.JobReport_
var cnd = destinationNode.Nodes[idx];
UpdateParentInfo(cnd, inseritem);
}
//AR.UTIL.MsgE("카테고리 이동은 불가 합니다");
}
else
{ // 노드 이동
if (destinationNode.Level > 1)
if (destinationNode.Level > 2)
{
UTIL.MsgE("최하위 레벨이하로는 이동할 수 없습니다");
}
else if (destinationNode.Level > 1)
{
var idx = destinationNode.Parent.Nodes.Add((TreeNode)draggedNode.Clone());
var cnd = destinationNode.Parent.Nodes[idx];
@@ -146,7 +169,7 @@ namespace FPJ0000.JobReport_
if (cnd.Level == 1) //최하위
if (cnd.Level == 2) //최하위
{
var grp = cnd.Parent.Text;
var prc = cnd.Parent.Parent.Text;
@@ -155,7 +178,7 @@ namespace FPJ0000.JobReport_
if (newitem)
{
dsJobReport.CommonRow ndr = this.dsJobReport.Common.NewCommonRow();
//ndr.svalue2 = prc;
ndr.svalue2 = prc;
ndr.svalue = grp;
ndr.memo = cnd.Text;
ndr.wuid = FCOMMON.info.Login.no;
@@ -170,7 +193,7 @@ namespace FPJ0000.JobReport_
//기존정보를 업데이트한다
var dr = cnd.Tag as dsJobReport.CommonRow;
dr.svalue = grp;
// dr.svalue2 = prc;
dr.svalue2 = prc;
dr.EndEdit();
}
@@ -186,7 +209,7 @@ namespace FPJ0000.JobReport_
if (newitem)
{
dsJobReport.CommonRow ndr = this.dsJobReport.Common.NewCommonRow();
// ndr.svalue2 = prc;
ndr.svalue2 = prc;
ndr.svalue = cnd.Text;
ndr.memo = nd.Text;
ndr.wuid = FCOMMON.info.Login.no;
@@ -199,7 +222,7 @@ namespace FPJ0000.JobReport_
else
{
var dr = nd.Tag as dsJobReport.CommonRow;
// dr.svalue2 = prc;
dr.svalue2 = prc;
dr.EndEdit();
}
}
@@ -278,8 +301,19 @@ namespace FPJ0000.JobReport_
{
try
{
this.ta.Fill(this.dsJobReport.Common, FCOMMON.info.Login.gcode, GroupCode);
var fullname = this.FullName.Split('|');
var pc = fullname[0].ToString();
var grp = fullname.Length > 2 ? fullname[1].Trim() : string.Empty;
if (pc.isEmpty())
{
this.ta.Fill(this.dsJobReport.Common, FCOMMON.info.Login.gcode, GroupCode);
}
else
this.ta.FillByJobProcess(this.dsJobReport.Common, FCOMMON.info.Login.gcode, GroupCode, pc);
this.commonDataGridView.AutoResizeColumns();
}
catch (System.Exception ex)
{
@@ -296,6 +330,16 @@ namespace FPJ0000.JobReport_
this.Show();
System.Windows.Forms.Application.DoEvents();
this.treeView1.Focus();
int curLevel = Math.Max(FCOMMON.info.Login.level, FCOMMON.DBM.getAuth(FCOMMON.DBM.eAuthType.jobreport));
this.bn.Enabled = (curLevel >= 5);
this.button2.Enabled = bn.Enabled;
this.btAdd.Enabled = bn.Enabled;
this.btEdit.Enabled = bn.Enabled;
this.groupBox3.Enabled = bn.Enabled;
this.groupBox4.Enabled = bn.Enabled;
this.commonDataGridView.ReadOnly = !bn.Enabled;
}
void RefreshTreeview()
{
@@ -316,23 +360,24 @@ namespace FPJ0000.JobReport_
var SelITM = bAutoselect ? selectedpath[2].Trim() : string.Empty;
if (SelPRC.isEmpty()) SelPRC = "N/A";
var grp_process = dsJobReport.Common.OrderBy(t => t.svalue).GroupBy(t => t.svalue);
var grp_process = dsJobReport.Common.OrderBy(t => t.svalue2).GroupBy(t => t.svalue2);
TreeNode autoSelectNode = null;
foreach (var grp in grp_process)
foreach (var prc in grp_process)
{
var grpname = grp.Key;
if (grpname.isEmpty()) grpname = "N/A";
if (grpname.Equals("(N/A)")) grpname = "N/A";
var prcname = prc.Key;
if (prcname.isEmpty()) prcname = "N/A";
if (prcname.Equals("(N/A)")) prcname = "N/A";
var nd = treeView1.Nodes.Add(grpname, grpname); //add process node
//var grp_jobtype = prc.OrderBy(t => t.svalue).GroupBy(t => t.svalue);
//foreach (var grp in grp_jobtype) //job type
var nd = treeView1.Nodes.Add(prcname, prcname); //add process node
var grp_jobtype = prc.OrderBy(t => t.svalue).GroupBy(t => t.svalue);
foreach (var grp in grp_jobtype) //job type
{
//var nd2 = nd.Nodes.Add(grp.Key, grp.Key);
var nd2 = nd.Nodes.Add(grp.Key, grp.Key);
var grpname = grp.Key;
foreach (var item in grp.OrderBy(t => t.memo))
{
var nd3 = nd.Nodes.Add(item.memo, item.memo); //job item
if (grpname.Equals("N/A"))
var nd3 = nd2.Nodes.Add(item.memo, item.memo); //job item
if (prcname.Equals("N/A"))
nd3.ForeColor = Color.DimGray;
else
nd3.ForeColor = Color.Black;
@@ -340,7 +385,7 @@ namespace FPJ0000.JobReport_
if (bAutoselect)
{
if (grpname.Equals(SelGRP) && item.memo.Equals(SelITM))
if (prcname.Equals(SelPRC) && grpname.Equals(SelGRP) && item.memo.Equals(SelITM))
{
autoSelectNode = nd3;
}
@@ -348,14 +393,24 @@ namespace FPJ0000.JobReport_
}
}
}
treeView1.ExpandAll(); //show all
this.treeView1.CollapseAll();
groupBox3.Enabled = false;
if (autoSelectNode != null)
{
this.treeView1.SelectedNode = autoSelectNode;
this.treeView1.SelectedNode.EnsureVisible();
this.treeView1.SelectedNode.Expand();
this.treeView1.Focus();
}
else
{
if(this.treeView1.Nodes.Count > 0)
this.treeView1.Nodes[0].Expand();
}
}
@@ -367,7 +422,7 @@ namespace FPJ0000.JobReport_
{
try
{
var cols = new string[] { "svalue2", "svalue", "memo" };
var cols = new string[] { "svalue", "memo" };
var filterstring = "";
foreach (var col in cols)
{
@@ -406,18 +461,25 @@ namespace FPJ0000.JobReport_
RefreshTreeview();
}
private void button2_Click(object sender, EventArgs e)
private void btEdit_Click(object sender, EventArgs e)
{
//edit
var prc = tbProcessE.Text.Trim();
var grp = tbTypeE.Text.Trim();
var item = tbItemE.Text.Trim();
if (item.isEmpty())
{
UTIL.MsgE("형태는 반드시 입력되어야 합니다");
tbItemE.Focus();
return;
}
if (prc.isEmpty())
{
UTIL.MsgE("프로세스가 입력되지 않았습니다");
tbProcessE.Focus();
return;
}
var nd = this.treeView1.SelectedNode;
if (nd == null)
@@ -432,7 +494,7 @@ namespace FPJ0000.JobReport_
}
//동일데이터가있는지확인
var exist = this.dsJobReport.Common.Where(t => t.RowState != DataRowState.Deleted && t.svalue.Equals(grp) && t.memo.Equals(item)).Any();
var exist = this.dsJobReport.Common.Where(t => t.RowState != DataRowState.Deleted && t.svalue2.Equals(prc) && t.svalue.Equals(grp) && t.memo.Equals(item)).Any();
if (exist)
{
UTIL.MsgE("동일한 항목이 존재합니다 / 확인 후 다시 진행 하세요");
@@ -443,7 +505,7 @@ namespace FPJ0000.JobReport_
var dr = nd.Tag as dsJobReport.CommonRow;
if (dr == null) return;
var changecate = dr.svalue2.Equals(prc) == false || dr.svalue.Equals(grp) == false;
var changecate = (dr.svalue2.Equals(prc) == false || dr.svalue.Equals(grp) == false);
dr.svalue2 = prc;
dr.svalue = grp;
@@ -452,7 +514,7 @@ namespace FPJ0000.JobReport_
//카테고리가 변경되었다면 위치를 이동시켜야한다
nd.Remove(); //선택노드를 삭제한다.
AddNode(prc, grp, item, dr);
AddNode(prc,grp, item, dr);
@@ -460,8 +522,11 @@ namespace FPJ0000.JobReport_
void AddNode(string prc, string grp, string item, dsJobReport.CommonRow dr)
{
//프로세스 노드 선택
TreeNode tn_grp = null;
TreeNode tn_prc = null;
if (grp.isEmpty()) grp = "N/A";
if (prc.isEmpty()) prc = "N/A";
var prc_nodes = this.treeView1.Nodes.Find(prc, false);
if (prc_nodes.Any() == false)
{
@@ -472,25 +537,25 @@ namespace FPJ0000.JobReport_
tn_prc = prc_nodes.First(); //첫번째 노드로 변경
}
//분류노드확인
TreeNode tn_type = null;
var type_nodes = tn_prc.Nodes.Find(grp, false);
if (type_nodes.Any() == false)
var grp_nodes = tn_prc.Nodes.Find(grp, false);
if (grp_nodes.Any() == false)
{
tn_type = tn_prc.Nodes.Add(grp, grp); //신규노드추가
tn_grp = tn_prc.Nodes.Add(grp, grp); //신규노드추가
}
else
{
tn_type = type_nodes.First(); //첫번째 노드로 변경
tn_grp = grp_nodes.First(); //첫번째 노드로 변경
}
//아이템노드확인
TreeNode tn_item = null;
var item_nodes = tn_type.Nodes.Find(item, false);
var item_nodes = tn_grp.Nodes.Find(item, false);
if (item_nodes.Any() == false)
{
tn_item = tn_type.Nodes.Add(item, item); //신규노드추가
tn_item = tn_grp.Nodes.Add(item, item); //신규노드추가
}
else
{
@@ -500,14 +565,24 @@ namespace FPJ0000.JobReport_
tn_item.Tag = dr;
treeView1.SelectedNode = tn_item;
treeView1.SelectedNode.EnsureVisible();
}
private void button3_Click(object sender, EventArgs e)
{
//add
var prc = tbProcessA.Text.Trim();
var grp = tbTypeA.Text.Trim();
var item = tbItemA.Text.Trim();
var prc = tbProcessI.Text.Trim();
if (prc.isEmpty())
{
UTIL.MsgE("프로세스가 입력되지 않았습니다");
tbProcessI.Focus();
return;
}
if (item.isEmpty())
{
UTIL.MsgE("형태는 반드시 입력되어야 합니다");
@@ -576,13 +651,15 @@ namespace FPJ0000.JobReport_
var dr = tn.Tag as dsJobReport.CommonRow;
if (dr == null) return;
tbProcessE.Text = dr.svalue2;
tbTypeE.Text = dr.svalue;
tbItemE.Text = dr.memo;
tbProcessA.Text = dr.svalue2;
tbTypeA.Text = dr.svalue;
tbItemE.Text = dr.memo;
tbItemA.Text = dr.memo;
tbProcessE.Text = dr.svalue2;
tbProcessI.Text = dr.svalue2;
groupBox3.Enabled = true;
groupBox3.Text = $"선택자료 편집({dr.idx})";
@@ -600,60 +677,11 @@ namespace FPJ0000.JobReport_
btEdit.PerformClick();
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
UTIL.MsgI("목록화면고 동일한 배치의 데이터를 클립보드에서 가져옵니다\n(항목/분류/프로세스)");
var data = Clipboard.GetText();
var lines = data.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var dlg = UTIL.MsgQ($"{lines.Length} 개의 데이터가 있습니다.\n\n입력 할까요?");
if (dlg != DialogResult.Yes) return;
var icnt = 0;
var scnt = 0;
var ecnt = 0;
foreach (var line in lines)
{
var buf = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
var item = buf[0].Trim();
if (item.isEmpty())
{
ecnt += 1;
continue;
}
var grp = buf.Length > 1 ? buf[1].Trim() : string.Empty;
var prc = buf.Length > 2 ? buf[2].Trim() : string.Empty;
//동일항목체크
if (this.dsJobReport.Common.Where(t => t.RowState != DataRowState.Detached && t.RowState != DataRowState.Deleted &&
t.memo.Equals(item) && t.svalue.Equals(grp) && t.svalue2.Equals(prc)).Any())
{
scnt += 1;
continue;
}
icnt += 1;
var dr = this.dsJobReport.Common.NewCommonRow();
dr.svalue2 = prc;
dr.svalue = grp;
dr.memo = item;
dr.wuid = FCOMMON.info.Login.no;
dr.wdate = DateTime.Now;
dr.grp = this.GroupCode;
dr.code = makenewcode();
this.dsJobReport.Common.AddCommonRow(dr);
}
var msg = $"가져오기 결과 입니다\n\n추가:{icnt}\n중복:{scnt}\n오류:{ecnt}";
AR.UTIL.MsgI(msg);
if (icnt > 0)
RefreshTreeview();
}
private void button2_Click_1(object sender, EventArgs e)
{
//edit
//선택노드삭제
var nd = this.treeView1.SelectedNode;
if (nd == null)
{
@@ -668,18 +696,21 @@ namespace FPJ0000.JobReport_
//동일데이터가있는지확인
var dr = nd.Tag as dsJobReport.CommonRow;
var prc = dr.svalue2;
var grp = dr.svalue;
var prc = dr.svalue2;
var item = dr.memo;
var exist = this.dsJobReport.Common.Where(t => t.RowState != DataRowState.Deleted && t.svalue2.Equals(prc) && t.svalue.Equals(grp) && t.memo.Equals(item)).FirstOrDefault();
var exist = this.dsJobReport.Common.Where(t => t.RowState != DataRowState.Deleted &&
t.svalue2.Equals(prc) && t.svalue.Equals(grp) && t.memo.Equals(item)).FirstOrDefault();
if (exist == null)
{
UTIL.MsgE("해당 데이터를 찾지 못했습니다\n잠시 후 다시 시도하세요");
return;
}
exist.Delete(); // dsJobReport.Common.RemoveCommonRow(exist);
RefreshTreeview();
nd.Remove();
//RefreshTreeview();
}
private void btDelete_Click(object sender, EventArgs e)
@@ -716,10 +747,12 @@ namespace FPJ0000.JobReport_
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (this.FullName.isEmpty()) return;
//노드에서 항목 더블클릭
var nd = this.treeView1.SelectedNode;
if (nd == null) return;
if (nd.Level < 2) return;
if (nd.Level < 1) return;
var dr = nd.Tag as dsJobReport.CommonRow;
if (dr == null) return;
Feedback(dr);
@@ -730,7 +763,7 @@ namespace FPJ0000.JobReport_
//트리뷰항목 선택
var nd = this.treeView1.SelectedNode;
if (nd == null) return;
if (nd.Level < 2)
if (nd.Level < 1)
{
UTIL.MsgE("최하위 항목을 선택하세요");
return;
@@ -743,6 +776,8 @@ namespace FPJ0000.JobReport_
private void commonDataGridView_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
//데이터그리드뷰 항목 더블클릭
if (this.FullName.isEmpty()) return;
var drv = bs.Current as DataRowView;
if (drv == null) return;
var dr = drv.Row as dsJobReport.CommonRow;
@@ -752,17 +787,108 @@ namespace FPJ0000.JobReport_
void Feedback(dsJobReport.CommonRow dr)
{
var prc = dr.svalue2;
var grp = dr.svalue;
var itm = dr.memo;
if (prc.isEmpty()) prc = "N/A";
if (grp.isEmpty()) grp = "N/A";
this.SelectedValue = $"{prc}|{grp}|{itm}";
DialogResult = DialogResult.OK;
}
public string SelectedValue { get; set; } = "";
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
if(this.haschanged())
{
AR.UTIL.MsgE("변경된 자료가 존재합니다.\n현재 자료를 저장하거나 화면을 다시 호출 하세요");
return;
}
UTIL.MsgI("목록화면고 동일한 배치의 데이터를 클립보드에서 가져옵니다\n(항목/분류/프로세스)");
var data = Clipboard.GetText();
var lines = data.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var dlg = UTIL.MsgQ($"{lines.Length} 개의 데이터가 있습니다.\n\n입력 할까요?");
if (dlg != DialogResult.Yes) return;
var icnt = 0;
var scnt = 0;
var ecnt = 0;
foreach (var line in lines)
{
var buf = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
var item = buf[0].Trim();
if (item.isEmpty())
{
ecnt += 1;
continue;
}
var grp = buf.Length > 1 ? buf[1].Trim() : string.Empty;
var prc = buf.Length > 2 ? buf[2].Trim() : string.Empty;
//동일항목체크
if (this.dsJobReport.Common.Where(t => t.RowState != DataRowState.Detached && t.RowState != DataRowState.Deleted &&
t.memo.Equals(item) && t.svalue2.Equals(prc) && t.svalue.Equals(grp)).Any())
{
scnt += 1;
continue;
}
icnt += 1;
var dr = this.dsJobReport.Common.NewCommonRow();
dr.svalue = grp;
dr.svalue2 = prc;
dr.memo = item;
dr.wuid = FCOMMON.info.Login.no;
dr.wdate = DateTime.Now;
dr.grp = this.GroupCode;
dr.code = makenewcode();
this.dsJobReport.Common.AddCommonRow(dr);
}
var msg = $"가져오기 결과 입니다\n\n추가:{icnt}\n중복:{scnt}\n오류:{ecnt}";
AR.UTIL.MsgI(msg);
if (icnt > 0)
RefreshTreeview();
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
var dlg = UTIL.MsgQ("현재 목록 데이터를 삭제할까요?\n저장을 하면 최종 서버에 적용 됩니다");
if (dlg != DialogResult.Yes) return;
var cnt = 0;
while (bs.Count > 0)
{
bs.RemoveCurrent();
cnt += 1;
}
UTIL.MsgI($"{cnt}건의 자료가 삭제되었습니다\n저장버튼을 누르면 데이터베이스에 적용 됩니다");
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
var sb = new System.Text.StringBuilder();
sb.AppendLine("항목\t분류\t프로세스");
var filterdata = this.dsJobReport.Common.Select(this.bs.Filter, this.bs.Sort);
var cnt = 0;
foreach (dsJobReport.CommonRow dr in filterdata)
{
if (dr.RowState == DataRowState.Deleted || dr.RowState == DataRowState.Detached) continue;
cnt += 1;
sb.AppendLine($"{dr.memo}\t{dr.svalue}\t{dr.svalue2}");
}
Clipboard.SetText(sb.ToString());
AR.UTIL.MsgI($"{cnt}건의 자료가 클립보드에 입력되었습니다\n엑셀등의 프로그램에서 Ctrl+V 하세요");
}
private void button1_Click_1(object sender, EventArgs e)
{
this.treeView1.ExpandAll();
}
private void button3_Click_1(object sender, EventArgs e)
{
this.treeView1.CollapseAll();
}
}
}