---
# System prepended metadata

title: Nuntio維護清單

---

# Nuntio維護清單
[TOC]



### **Problem:** 在無更動版本下可以不斷update更版
**Soultion:**

先在`LoadReportButtonClick(object objectParameter)`加入`ReportModified.ModifiedFlag = false;`把頁面更動紀錄在點show report的click後就初始化為無更動(false)

```c#
private void LoadReportButtonClick(object objectParameter)
        {
            try
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
                var reportRecord = objectParameter as ReportRecord;
                if (reportRecord == null)
                    return;
                LoadReportTemplate(reportRecord);
                XlsInquiryConditionVM.CurrentReportRecord = reportRecord;
                XlsViewerVM.SetEventVM(reportRecord.ReportID, reportRecord.ReportInstance.ReportInstanceId);
                ReportModified.ModifiedFlag = false;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }
```
在`UpdateReport(object commandParameter)`加入`if (ReportModified.CheckModified()){}`判斷畫面有沒有被更動，如果沒有更動就要update會跳出messagebox顯示You make no modify.
```c#
        private void UpdateReport(object commandParameter)
        {
            try
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
                if (ReportModified.CheckModified())
                {
                    var valid = Validate();
                    if (valid)
                    {
                        BeforeUpdateClick();
                        XlsViewerVM.UpdateReport(commandParameter);
                        AfterUpdateClick();
                    }
                    else
                    {
                        MessageBox.Show("Update not yet.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("You make no modify.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                    
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }
```
---
### **Problem:** 在無更動版本下可以check (增加messagebox做double check)
**Soultion:**

在private void CheckReport(bool isUpdateCheck)的else中加入`var dr = MessageBox.Show("Are you sure you want to CHECK report?", "Information", MessageBoxButtons.YesNo, MessageBoxIcon.Information);`並寫上 if 做 yes 時的動作（將原動作加入yes並把`_doNothing`mark為`false`） , no 的話 `_doNothing = true;` and` return;`。

```c#
        private void CheckReport(bool isUpdateCheck)
        {
            try
            {
                if (isUpdateCheck)
                {
                    XlsServiceProxy.ConfirmReports(new List<ArReportInst>
                    {
                        XlsServiceProxy.GetReportAndVersionList
                            (
                                false,
                                ReportQueryMode,
                                User.Info.Branch,
                                XlsViewerVM.HandleDate,
                                XlsInquiryConditionVM.CurrentReportRecord.ReportID
                            )[0]
                    });
                }
                else
                {
                    var dr = MessageBox.Show("Are you sure you want to CHECK report?", "Information", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                    if (dr == DialogResult.Yes)
                    {
                        XlsServiceProxy.ConfirmReports(new List<ArReportInst>
                        {
                        XlsInquiryConditionVM.CurrentReportRecord.ReportInstance
                        });
                        _doNothing = false;
                    }
                    else
                    {
                        _doNothing = true;
                        return;
                    }
                }
                MessageBox.Show("CHECK SUCCESSFUL!", "SUCCESSFUL", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());
            }
        }
```
---
### ？**Problem:** XLS欄位中只能輸入float or int，遇到日期時無法更改日期類型資料
**Soultion:**

---
### **Problem:** Update, Check toolbar功能需要有messagebox讓user知道有完成執行
**Soultion:**

(Update)
在`ReportModifyViewModel.cs`的`protected override void AfterUpdateClick()`中加入`MessageBox.Show("UPDATE SUCCESSFUL!", "SUCCESSFUL", MessageBoxButtons.OK, MessageBoxIcon.Information);`
```c#
        protected override void AfterUpdateClick()
        {
            base.AfterUpdateClick();
            //20160621 Daniel:after update set modified flag false.
            MessageBox.Show("UPDATE SUCCESSFUL!", "SUCCESSFUL", MessageBoxButtons.OK, MessageBoxIcon.Information);
            ReportModified.ModifiedFlag = false;
            CellInfoSetReadOnly();
        }
```

(Check)
在`ReportModifyViewModel.cs`的`private void CheckReport(bool isUpdateCheck)`中 `try{}` 加入`MessageBox.Show("CHECK SUCCESSFUL!", "SUCCESSFUL", MessageBoxButtons.OK, MessageBoxIcon.Information);`
```c#
        private void CheckReport(bool isUpdateCheck)
        {
            try
            {
                if (isUpdateCheck)
                {
                    XlsServiceProxy.ConfirmReports(new List<ArReportInst>
                    {
                        XlsServiceProxy.GetReportAndVersionList
                            (
                                false,
                                ReportQueryMode,
                                User.Info.Branch,
                                XlsViewerVM.HandleDate,
                                XlsInquiryConditionVM.CurrentReportRecord.ReportID
                            )[0]
                    });
                }
                else
                {
                    XlsServiceProxy.ConfirmReports(new List<ArReportInst>
                    {
                        XlsInquiryConditionVM.CurrentReportRecord.ReportInstance
                    });
                }
                MessageBox.Show("CHECK SUCCESSFUL!", "SUCCESSFUL", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());
            }
        }
```
- Execute, Reject 因為在欄位中會顯示success所以不做

---
### **Problem:** Reject or Execute沒有select也可以執行
**Soultion:**

目前方法:
加入`using System.Windows.Forms;` and `using MessageBox = System.Windows.Forms.MessageBox;`
用`XlsInquiryConditionVM.ReportRecordCollection
                       .Where(record => record.IsSelected)
                       .Select(record => record.ReportInstance)
                       .ToList();`回傳的結果做長度判斷 count == 0 表示沒有選定項目。
```c#
        protected override void ExecuteSelectedReport()
        {
            try
            {
                var ExecutedSelected = XlsInquiryConditionVM.ReportRecordCollection
                       .Where(record => record.IsSelected)
                       .Select(record => record.ReportInstance)
                       .ToList();
                IList<ReportStatusResult> result = XlsServiceProxy.VerifyReports(ExecutedSelected, Sm.CommentList);

                if (ExecutedSelected.Count() == 0)
                {
                    MessageBox.Show("You have selected nothing.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                if (result == null)
                {
                    MessageBox.Show("Error occured when refresh result");
                    return;
                }

                foreach (ReportStatusResult reportStatus in result)
                {
                    RefreshReportStatus(reportStatus);
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
```
---
其他可能方法:
將`ExecuteSelectedReport()`從 void 改作其他可以回傳資料的型態

ReportNotOKayViewmodel.cs 更改`ExecuteSelectedReport()`為回傳 string 如下:
```c#
protected override string ExecuteSelectedReport()
        {
            try
            {
                var ExecutedSelected = XlsInquiryConditionVM.ReportRecordCollection
                    .Where(record => record.IsSelected)
                    .Select(record => record.ReportInstance)
                    .ToList();
                IList <ReportStatusResult> result = XlsServiceProxy.NotOkReports(ExecutedSelected, Sm.CommentList);
                if (ExecutedSelected.Count() == 0)
                {
                    //MessageBox.Show("You have selected nothing.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return "You have selected nothing.";
                }

                if (result == null)
                {
                    //MessageBox.Show("Error occured when refresh result");
                    return "Error occured when refresh result";
                }

                foreach (ReportStatusResult reportStatus in result)
                {
                    RefreshReportStatus(reportStatus);
                }
                return "Successful";
            }
            catch (Exception exception)
            {
                //MessageBox.Show(exception.Message);
                return "Exception: " + exception.Message;
            }
        }
```

ReportVerifyViewmodel.cs 更改`ExecuteSelectedReport()` `RejectSelectedReport()`為回傳 string 如下:
```c#
protected override string ExecuteSelectedReport()
        {
            try
            {
                var ExecutedSelected = XlsInquiryConditionVM.ReportRecordCollection
                       .Where(record => record.IsSelected)
                       .Select(record => record.ReportInstance)
                       .ToList();
                IList<ReportStatusResult> result = XlsServiceProxy.VerifyReports(ExecutedSelected, Sm.CommentList);

                if (ExecutedSelected.Count() == 0)
                {
                    //MessageBox.Show("You have selected nothing.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return "You have selected nothing.";
                }

                if (result == null)
                {
                    //MessageBox.Show("Error occured when refresh result");
                    return "Error occured when refresh result";
                }

                foreach (ReportStatusResult reportStatus in result)
                {
                    RefreshReportStatus(reportStatus);
                }
                return "Verify complete";
            }
            catch (Exception exception)
            {
                //MessageBox.Show(exception.Message);
                return "Exception: " + exception.Message;
            }
        }

        #endregion

        #region Reject

        protected override string RejectSelectedReport()
        {
            try
            {
                var RejectSelected = XlsInquiryConditionVM.ReportRecordCollection
                    .Where(record => record.IsSelected)
                    .Select(record => record.ReportInstance)
                    .ToList();
                IList<ReportStatusResult> result = XlsServiceProxy.RejectReports(RejectSelected, Sm.CommentList);

                if (RejectSelected.Count() == 0)
                {
                    //MessageBox.Show("You have selected nothing.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return "You have selected nothing.";
                }

                if (result == null)
                {
                    //MessageBox.Show("Error occured when refresh result");
                    return "Error occured when refresh result";
                }

                foreach (ReportStatusResult reportStatus in result)
                {
                    RefreshReportStatus(reportStatus);
                }
                return "Reject complete";
            }
            catch (Exception exception)
            {
                //MessageBox.Show(exception.Message);
                return "Exception: " + exception.Message;
            }
        }
```

ReportManagerViewModel.cs 更改為使用字串判斷回傳後發出messagebox更改如下:
```c#
#region Execute：覆核單張或多張報表: Verify/ 解控報表單張或多張報表: Not Okay

        public ICommand ExecuteClickCommand
        {
            get
            {
                return _executeClickCommand ?? (_executeClickCommand = CommandFactory.CreateCommand<object>(ExecuteReport));
            }
        }

        private void ExecuteReport(object commandParameter)
        {
            try
            {
                if (ExecuteSelectedReport().Equals("Verify complete"))
                {
                    MessageBox.Show("Verify complete", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    AfterExecuteClick();
                }
                else if (ExecuteSelectedReport().Equals("Successful"))
                {
                    MessageBox.Show("Successful", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    AfterExecuteClick();
                }
                else if (ExecuteSelectedReport().Equals("You have selected nothing."))
                {
                    MessageBox.Show(ExecuteSelectedReport(), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else if (ExecuteSelectedReport().Equals("Error occured when refresh result"))
                {
                    MessageBox.Show("Error occured when refresh result");
                }
                else if (ExecuteSelectedReport().Equals("Exception: "))
                {
                    MessageBox.Show(ExecuteSelectedReport());
                }
                //ExecuteSelectedReport();
                //AfterExecuteClick();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }

        protected virtual string ExecuteSelectedReport()
        {
            return "";
            // intentionaly empty
            // override: VerifyViewModel
            // override: NotOkayViewModel
        }

        #endregion

        #region Reject：解控畫面上的報表為該申報日待覆核報表

        // ViewModelBase
        public ICommand RejectClickCommand
        {
            get
            {
                return _rejectClickCommand ?? (_rejectClickCommand = CommandFactory.CreateCommand<object>(RejectReport));
            }
        }

        private void RejectReport(object commandParameter)
        {
            try
            {
                try
                {
                    if (RejectSelectedReport().Equals("Reject complete"))
                    {
                        MessageBox.Show("Reject complete", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        AfterRejectClick();
                    }
                    else if (RejectSelectedReport().Equals("You have selected nothing."))
                    {
                        MessageBox.Show(ExecuteSelectedReport(), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else if (RejectSelectedReport().Equals("Error occured when refresh result"))
                    {
                        MessageBox.Show("Error occured when refresh result");
                    }
                    else if (RejectSelectedReport().Equals("Exception: "))
                    {
                        MessageBox.Show(ExecuteSelectedReport());
                    }
                    //RejectSelectedReport();
                    //AfterRejectClick();
                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
                throw;
            }
        }

        protected virtual string RejectSelectedReport()
        {
            return "";
            // intentionaly empty
            // override: Verify
        }

        #endregion
```

---
### ~~**Problem:** Action Detail 沒有作用~~
~~**Soultion:**~~

顯示ErrorMessage
ShowActionErrorMessageCommand

---
### **Problem:** Reject 後按鈕仍亮著
**Soultion:**

<mark>找不到原因</mark>
嘗試過將`ExecuteIsEnable = false;`及` RejectIsEnable = false;`直接寫在原來`AfterRejectClick();`的位置皆沒有作用。

下方Code改為`protected virtual void AfterRejectClick()` 
```c#
        private void AfterRejectClick()
        {
            ToolbarManipulation(Switch.Off);
            // VerifyViewModel
        }
```
並在 ReportVerifyViewModel.cs 中放入:
```
        protected override void AfterRejectClick()
        {
            base.AfterRejectClick();
            ToolbarManipulation(Switch.Off);
        }
```
一樣沒有作用。
檢查過testview.Toolbar
.xaml and .cs 沒有binding錯誤

* <mark>2021/11/24 找到原因，但對解法沒有想法</mark>
  主因是 Toolbar.xaml 中 對 image 還有 textblock 設定 `IsMouseDirectlyOverChanged` 所造成。移除後即正常但就沒有mouseon變亮的功能了。


---
### **Problem:** Modify Report 執行cancel後 xls視窗檔名沒有一併清除復原
**Soultion:**

在 XlsViewerModel.cs 的`public void Clear()` 中加入 `ReportName = "";` 將 ReportName 設定在 clear() 時是空的。

```c#
public void Clear()
        {
            File = ""; // ExtendedWorkbook當File=""時會產生空白報表
            ReportName = "";
            XlsDetailVM.SetDefault();
            CellInfoHasBeenModified = false;//20160617 Daniel add.
        }
```

---
### **Problem:** calander對比
**Soultion:**

`sqlExpression = "SELECT DISTINCT(BSN_DATE) FROM NU_CBBSND ORDER BY BSN_DATE;";`
BSN DATE?
DB中只有5筆資料

---
### **Problem:** cell information 中 Confrim 改comment也可confirm
**Soultion:**

`XlsCellInfoViewModel.cs` 中的 `public bool EditCellInstance(bool _cellInfoHasBeenModified)` `if (!CellInfoColumn.OriginalValue.ToString().Equals(newValue))` else 迴圈中將 `System.Windows.Forms.MessageBox.Show("Invalid request.", "Warning", MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);` 改為下面的 if
```c#
if (!CellInfoColumn.OriginalComment.ToString().Equals(comment))
                    {
                        CellInfoColumn.Value = newValue;
                        CellInfoColumn.Comment = comment;
                        //cellInfoProperty.CellInfoColumn.OriginalComment = comment;    //20151217 Glacier: set in RowProvider

                        cellInfoHasBeenModified = true;
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("Invalid request.", "Warning", MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);
                    }
```
---
### **Problem:** 當一個使用者modify報表時，另一不能進入報表
**Soultion:**

XlsxService.cs 加入 `GetReprotAccessLog()`, `InsertReportAccessLog()`, `UpdateReportAccessLog()`
```c#
        public virtual DataTable GetReportAccessLog(string[] parameter)  //string array [0]userid [1]RPT_INST_ID
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ROW_IDX");
            dt.Columns.Add("USERID");
            dt.Columns.Add("BRANCH");
            dt.Columns.Add("RPT_INST_ID");
            dt.Columns.Add("REQUEST_TIME_BEGIN");
            dt.Columns.Add("REQUEST_TIME_END");
            dt.TableName = "DataTableName";

            using (var session = DatabaseFactory.CreateDatabaseSession())
            {
                var accesslog = session.GetRepository<ArReportAccessLog>();

                if (string.IsNullOrEmpty(parameter[0].Trim()))
                {
                    Expression<Func<ArReportAccessLog, bool>> expr =
                        item => item.RptInstId.ToString() == parameter[1];
                    var basicquery = accesslog.FilterBy(expr);

                    foreach (var reportCtrl in basicquery)
                    {
                        DataRow row = dt.NewRow();
                        row["ROW_IDX"] = reportCtrl.RowIdx;
                        row["USERID"] = reportCtrl.Userid;
                        row["BRANCH"] = reportCtrl.Branch;
                        row["RPT_INST_ID"] = reportCtrl.RptInstId;
                        row["REQUEST_TIME_BEGIN"] = reportCtrl.RequestTimeBegin;
                        row["REQUEST_TIME_END"] = reportCtrl.RequestTimeEnd;
                        dt.Rows.Add(row);
                        //break;
                    }
                }
                else if (!string.IsNullOrEmpty(parameter[0]))
                {
                    if (string.IsNullOrEmpty(parameter[1].Trim()))
                    {
                        Expression<Func<ArReportAccessLog, bool>> expr =
                            item => item.Userid == parameter[0];
                        var basicquery = accesslog.FilterBy(expr);

                        foreach (var reportCtrl in basicquery)
                        {
                            DataRow row = dt.NewRow();
                            row["ROW_IDX"] = reportCtrl.RowIdx;
                            row["USERID"] = reportCtrl.Userid;
                            row["BRANCH"] = reportCtrl.Branch;
                            row["RPT_INST_ID"] = reportCtrl.RptInstId;
                            row["REQUEST_TIME_BEGIN"] = reportCtrl.RequestTimeBegin;
                            row["REQUEST_TIME_END"] = reportCtrl.RequestTimeEnd;
                            dt.Rows.Add(row);
                            //break;
                        }
                    }
                    else
                    {
                        Expression<Func<ArReportAccessLog, bool>> expr =
                            item => item.RptInstId.ToString() == parameter[1].Trim() && item.Userid.ToString() == parameter[0].Trim();
                        var basicquery = accesslog.FilterBy(expr);
                        foreach (var reportCtrl in basicquery)
                        {
                            DataRow row = dt.NewRow();
                            row["ROW_IDX"] = reportCtrl.RowIdx;
                            row["USERID"] = reportCtrl.Userid;
                            row["BRANCH"] = reportCtrl.Branch;
                            row["RPT_INST_ID"] = reportCtrl.RptInstId;
                            row["REQUEST_TIME_BEGIN"] = reportCtrl.RequestTimeBegin;
                            row["REQUEST_TIME_END"] = reportCtrl.RequestTimeEnd;
                            dt.Rows.Add(row);
                            //break;
                        }
                    }
                }
                session.Dispose();
            }

            return dt;

        }

        public virtual void InsertReportAccessLog(string branch, int rptinstid)
        {
            
            using (var session = DatabaseFactory.CreateDatabaseSession())
            {
                var accesslog = session.GetRepository<ArReportAccessLog>();
                session.BeginTransaction();
                try
                {
                    var accesslog1 = new ArReportAccessLog()
                    {
                        Userid = User.AccountId,
                        Branch = branch,
                        RptInstId = rptinstid,
                        RequestTimeBegin = DateTime.Now,
                        RequestTimeEnd = null
                    };
                    accesslog.Insert(accesslog1);
                    session.Commit();
                }
                catch (Exception ex)
                {

                    Log.Error("InsertArReportLog ERROR");
                    Log.Error(ex);
                    throw;
                }
                finally
                {
                    Log.Info("InsertArReportLog OK");
                    session.Dispose();
                }
            }
        }

        public virtual void UpdateReportAccessLog(string userid, int rowidx)
        {
            using (var session = DatabaseFactory.CreateDatabaseSession())
            {
                try
                {
                    var accesslog = session.GetRepository<ArReportAccessLog>();
                    session.BeginTransaction();
                    Expression<Func<ArReportAccessLog, bool>> expr =
                        item => item.Userid == userid && item.RowIdx == rowidx;
                    var basicquary = accesslog.FilterBy(expr);
                    foreach (var accesslog1 in basicquary)
                    {
                        accesslog1.RequestTimeEnd = DateTime.Now;
                        accesslog.Update(accesslog1);
                        break;
                    }

                    session.Commit();
                }
                catch (Exception ex)
                {
                    Log.Error("UpdateArReportAccessLog ERROR");
                    Log.Error(ex);
                }
                finally
                {
                    Log.Info("UpdateArReportAccessLog OK");
                    session.Dispose();
                }
            }
        }
```
---

XlsxServiceProxy.cs 加入
```c#
        public DataTable GetReportAccessLog(string[] parameter)
        {
            return _xlsxReportClient.GetReportAccessLog(parameter);
        }

        public void InsertReportAccessLog(string branch, int rptinstid)
        {
            _xlsxReportClient.InsertReportAccessLog(branch, rptinstid);
        }

        public void UpdateReportAccessLog(string userid, int rowidx)
        {
            _xlsxReportClient.UpdateReportAccessLog(userid, rowidx);
        }
```
---
XlsxReportClient.cs 加入
```c#
        public DataTable GetReportAccessLog(string[] parameter)
        {
            return Channel.GetReportAccessLog(parameter);
        }

        public void InsertReportAccessLog(string branch, int rptinstid)
        {
            Channel.InsertReportAccessLog(branch, rptinstid);
        }

        public void UpdateReportAccessLog(string userid, int rowidx)
        {
            Channel.UpdateReportAccessLog(userid, rowidx);
        }
```
---
IXlsxService.cs 加入
```c#
        [OperationContract]
        [FaultContract(typeof(ServiceFault))]
        DataTable GetReportAccessLog(string[] parameter);

        [OperationContract]
        [FaultContract(typeof(ServiceFault))]
        void InsertReportAccessLog(string branch, int rptinstid);

        [OperationContract]
        [FaultContract(typeof(ServiceFault))]
        void UpdateReportAccessLog(string userid, int rowidx);
```
---
ReportManagerViewModel.cs 加入`GetandUpdateReportAccessLog()`
需要先Get DB 中該帳號的所有ReportAccessLog，並判斷回傳資料>0 (為了保有原command有的作動)，UpdateReportAccessLog最後一筆資料(使用Get時拿到的ROW_IDX最大值)。
//update要給accountid是多寫的，因為真正update時是呼叫`GetandUpdateReportAccessLog()` 在這邊get時已經先做過accountid的判斷拿到該帳號的最大值的ROW_IDX了。
```c#
        public void GetandUpdateReportAccessLog()
        {
            string[] accesslog_para = {User.Info.AccountId, ""};
            var accesslog = XlsServiceProxy.GetReportAccessLog(accesslog_para);
            var accesslogLength = accesslog.Rows.Count;
            if (accesslogLength > 0)
            {
                XlsServiceProxy.UpdateReportAccessLog(User.Info.AccountId, Convert.ToInt32(accesslog.Compute("max([ROW_IDX])", string.Empty)));
            }
        }
```
---
ReportManagerViewModel.cs `UpdateReport()` 加入 `GetandUpdateReportAccessLog();`
```c#
        private void UpdateReport(object commandParameter)
        {
            try
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
                if (ReportModified.CheckModified())
                {
                    var valid = Validate();
                    if (valid)
                    {
                        BeforeUpdateClick();
                        XlsViewerVM.UpdateReport(commandParameter);
                        GetandUpdateReportAccessLog();
                        AfterUpdateClick();
                    }
                    else
                    {
                        MessageBox.Show("Update not yet.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("You make no modify.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                    
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }

```
---
ReportManagerViewModel.cs CheckReport() 加入 GetandUpdateReportAccessLog();
```c#
        private void CheckReport(object commandParameter)
        {
            try
            {
                ModifyCheckReport();
                GetandUpdateReportAccessLog();
                AfterCheckClick();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }
```
---
ReportManagerViewModel.cs ExportReport() 加入 GetandUpdateReportAccessLog();
```c#
        private void ExportReport(object commandParameter)
        {
            try
            {
                SetExportReport(commandParameter);
                GetandUpdateReportAccessLog();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }
```
---
ReportManagerViewModel.cs ClearInquiryParameter() 加入 GetandUpdateReportAccessLog();
```c#
        private void ClearInquiryParameter(object objectParameter)
        {
            try
            {
                XlsInquiryConditionVM.Clear(_dataDate, _rptIdList);
                XlsViewerVM.Clear();
                GetandUpdateReportAccessLog();
                ToolbarManipulation(Switch.Off);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }
```
---
ReportManagerViewModel.cs LoadReportButtonClick() 更改為:
先Get資料庫中的資料(僅回傳該click表單的所有access紀錄)
```C#
string[] accesslog_para = {"", reportRecord.ReportInstance.ReportInstanceId.ToString()};
var accesslog = XlsServiceProxy.GetReportAccessLog(accesslog_para);
var accesslogLength = accesslog.Rows.Count;
```
加入判斷，如果沒有回傳資料就insert一筆新的，如果有回傳資料則要判斷"最後一筆資料"有沒有end時間，如果"有"endtime則做原本click應做的事，並insert一筆新的begintime。如果"沒有"endtime(`accesslog.Rows[accesslogLength-1]["REQUEST_TIME_END"] == DBNull.Value` 用是否為null判斷)則raise error messagebox。

full code:
```c#
        private void LoadReportButtonClick(object objectParameter)
        {
            try
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
                GetandUpdateReportAccessLog();
                var reportRecord = objectParameter as ReportRecord;
                if (reportRecord == null)
                    return;
                
                string[] accesslog_para = {"", reportRecord.ReportInstance.ReportInstanceId.ToString()};
                var accesslog = XlsServiceProxy.GetReportAccessLog(accesslog_para);
                var accesslogLength = accesslog.Rows.Count;

                if (accesslogLength > 0 && accesslog.Rows[accesslogLength-1]["REQUEST_TIME_END"] == DBNull.Value)
                {
                    MessageBox.Show("This report is locked by other user. Please wait.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                XlsServiceProxy.InsertReportAccessLog(User.Info.Branch, reportRecord.ReportInstance.ReportInstanceId);
                LoadReportTemplate(reportRecord);
                XlsInquiryConditionVM.CurrentReportRecord = reportRecord;
                XlsViewerVM.SetEventVM(reportRecord.ReportID, reportRecord.ReportInstance.ReportInstanceId);
                ReportModified.ModifiedFlag = false;              
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
            }
        }
```
---
ReportVerifyViewModel.cs 與 ReportNotOkayViewModel.cs  `DisplayReportOnPopUp()` 加入 if 判斷 `xlsTemplate.ShowDialog() == false` 並呼叫 `GetandUpdateReportAccessLog()` 

fullcode:
```c#
        protected override void DisplayReportOnPopUp()
        {
            var xlsTemplate = new Window
            {
                Content = new XlsViewer(XlsViewerVM),
                Title = XlsViewerVM.Report.Name,
            };
            //xlsTemplate.ShowDialog();
            if (xlsTemplate.ShowDialog() == false)
            {
                GetandUpdateReportAccessLog();
            }
        }
```
---
ReportModifyViewModel.cs 中將入解構子 `protected override void DisposeUnmanagedResources()` 
用於離開ReportModifyViewModel時執行`GetandUpdateAccessReport()`
```c#
        protected override void DisposeUnmanagedResources()
        {
            GetandUpdateReportAccessLog();
            base.DisposeUnmanagedResources();
        }
```

---

增加proxy 使用 SecurityServic
SecurityServic.cs 加入 `GetReportAccessLog()` `GetandUpdateReportAccessLog()` `UpdateReportAccessLog()`
```
        public virtual DataTable GetReportAccessLog(string[] parameter)  //string array [0]userid [1]RPT_INST_ID
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ROW_IDX");
            dt.Columns.Add("USERID");
            dt.Columns.Add("BRANCH");
            dt.Columns.Add("RPT_INST_ID");
            dt.Columns.Add("REQUEST_TIME_BEGIN");
            dt.Columns.Add("REQUEST_TIME_END");
            dt.TableName = "DataTableName";

            using (var session = _databaseFactory.CreateDatabaseSession())
            {
                var accesslog = session.GetRepository<ArReportAccessLog>();

                if (string.IsNullOrEmpty(parameter[0].Trim()))
                {
                    Expression<Func<ArReportAccessLog, bool>> expr =
                        item => item.RptInstId.ToString() == parameter[1];
                    var basicquery = accesslog.FilterBy(expr);

                    foreach (var reportCtrl in basicquery)
                    {
                        DataRow row = dt.NewRow();
                        row["ROW_IDX"] = reportCtrl.RowIdx;
                        row["USERID"] = reportCtrl.Userid;
                        row["BRANCH"] = reportCtrl.Branch;
                        row["RPT_INST_ID"] = reportCtrl.RptInstId;
                        row["REQUEST_TIME_BEGIN"] = reportCtrl.RequestTimeBegin;
                        row["REQUEST_TIME_END"] = reportCtrl.RequestTimeEnd;
                        dt.Rows.Add(row);
                        //break;
                    }
                }
                else if (!string.IsNullOrEmpty(parameter[0]))
                {
                    if (string.IsNullOrEmpty(parameter[1].Trim()))
                    {
                        Expression<Func<ArReportAccessLog, bool>> expr =
                            item => item.Userid == parameter[0];
                        var basicquery = accesslog.FilterBy(expr);

                        foreach (var reportCtrl in basicquery)
                        {
                            DataRow row = dt.NewRow();
                            row["ROW_IDX"] = reportCtrl.RowIdx;
                            row["USERID"] = reportCtrl.Userid;
                            row["BRANCH"] = reportCtrl.Branch;
                            row["RPT_INST_ID"] = reportCtrl.RptInstId;
                            row["REQUEST_TIME_BEGIN"] = reportCtrl.RequestTimeBegin;
                            row["REQUEST_TIME_END"] = reportCtrl.RequestTimeEnd;
                            dt.Rows.Add(row);
                            //break;
                        }
                    }
                    else
                    {
                        Expression<Func<ArReportAccessLog, bool>> expr =
                            item => item.RptInstId.ToString() == parameter[1].Trim() && item.Userid.ToString() == parameter[0].Trim();
                        var basicquery = accesslog.FilterBy(expr);
                        foreach (var reportCtrl in basicquery)
                        {
                            DataRow row = dt.NewRow();
                            row["ROW_IDX"] = reportCtrl.RowIdx;
                            row["USERID"] = reportCtrl.Userid;
                            row["BRANCH"] = reportCtrl.Branch;
                            row["RPT_INST_ID"] = reportCtrl.RptInstId;
                            row["REQUEST_TIME_BEGIN"] = reportCtrl.RequestTimeBegin;
                            row["REQUEST_TIME_END"] = reportCtrl.RequestTimeEnd;
                            dt.Rows.Add(row);
                            //break;
                        }
                    }
                }
                session.Dispose();
            }

            return dt;

        }
        public virtual void UpdateReportAccessLog(string userid, int rowidx)
        {
            using (var session = _databaseFactory.CreateDatabaseSession())
            {
                try
                {
                    var accesslog = session.GetRepository<ArReportAccessLog>();
                    session.BeginTransaction();
                    Expression<Func<ArReportAccessLog, bool>> expr =
                        item => item.Userid == userid && item.RowIdx == rowidx;
                    var basicquary = accesslog.FilterBy(expr);
                    foreach (var accesslog1 in basicquary)
                    {
                        accesslog1.RequestTimeEnd = DateTime.Now;
                        accesslog.Update(accesslog1);
                        break;
                    }

                    session.Commit();
                }
                catch (Exception ex)
                {
                    Log.Error("UpdateArReportAccessLog ERROR");
                    Log.Error(ex);
                }
                finally
                {
                    Log.Info("UpdateArReportAccessLog OK");
                    session.Dispose();
                }
            }
        }
        public void GetandUpdateReportAccessLog()
        {
            string[] accesslog_para = { _user.AccountId, "" };
            var accesslog = GetReportAccessLog(accesslog_para);
            var accesslogLength = accesslog.Rows.Count;
            if (accesslogLength > 0)
            {
                UpdateReportAccessLog(_user.AccountId, Convert.ToInt32(accesslog.Compute("max([ROW_IDX])", string.Empty)));
            }
        }
```

ISecurityServic.cs 中加入
```
        [OperationContract]
        [FaultContract(typeof(ServiceFault))]
        void GetandUpdateReportAccessLog();
```

SecurityClient.cs
```
        public void GetandUpdateReportAccessLog()
        {
            Channel.GetandUpdateReportAccessLog();
        }
```

shell.xaml.cs 中 private void Window_Closing() 加入判斷
```c#
            if (dr == System.Windows.Forms.DialogResult.Yes)
            {
                SecurityService.GetandUpdateReportAccessLog();
            }
            
```
---
### **Problem:** 增加customlized pagesize的功能
**Soultion:**


Viewmodel:
```c#
using System.Collections.Generic;
```

`public class Inquiry_Attribute_Definition_VM : ViewModelBase` 中加入

```c#
public class Inquiry_Attribute_Definition_VM : ViewModelBase
    {
        public List<int> itemkind { get; set; }
        public int selecteditemkind { get; set; }
        public int selecteditemkindindex { get; set; }
    }
```

`public Inquiry_Attribute_Definition_VM()` 中加入
```c#
        public Inquiry_Attribute_Definition_VM(IUser user, IApplicationFactory applicationFactory, ISampleService proxy)
            : base(user, applicationFactory)
        {
            itemkind = new List<int> {10, 20, 30, 40, 50};
            selecteditemkindindex = -1;
        }
```
---

xaml:
加入combobox
```xaml
            <Custom:XamComboEditor x:Name="Pagersize" HorizontalAlignment="Left" Margin="472,69,0,0" VerticalAlignment="Top" Width="47" Height="26"
                                   Text="10" ItemsSource="{Binding itemkind}" Grid.Row="1"/>
```

設定pagesize binding
```xaml
<ig:PagerSettings AllowPaging="Top" PageSize="{Binding Source={x:Reference Pagersize}, Path=SelectedItem}"/>
```
---

#### 2021/11/23 將Grid(Pages)整個移出獨立

總共有三個頁面使用 (Inquiry Attribute Definition, Inquiry Report Cell Definition, Inquiry Manual Entry log)

移出Grid，建立新xaml(命名為GridPager.xaml):
整頁模式，於原地再用 `<Grid.RowDefinitions>` 綁位置
```xaml
<UserControl x:Class="ares.client.module.View.GridPager"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ares.client.module.View"
             xmlns:ig="http://schemas.infragistics.com/xaml"
             xmlns:Custom="http://infragistics.com/Editors"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <!--<Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>-->

        <ig:XamGrid x:Name="TestDataGrid1"
                    ItemsSource="{Binding DataGrid_IS, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"  HeaderRowHeight="35" RowHeight="30" VerticalContentAlignment="Center" BorderBrush="Black" Margin="10,0,10,0" >

            <ig:XamGrid.PagerSettings >
                <ig:PagerSettings AllowPaging="Top" PageSize="{Binding Source={x:Reference Pagersize}, Path=SelectedItem}"/>
            </ig:XamGrid.PagerSettings>
            <ig:XamGrid.RowSelectorSettings>
                <ig:RowSelectorSettings Visibility="Visible" />
            </ig:XamGrid.RowSelectorSettings>
        </ig:XamGrid>
        <Label Content="Page size:" HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Top" />
        <Custom:XamComboEditor x:Name="Pagersize" HorizontalAlignment="Left" Margin="70,3,0,0" VerticalAlignment="Top" Width="45" Height="22" 
                               Text="10" ItemsSource="{Binding itemkind}" SelectedItem="{Binding selecteditemkind, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="{Binding selecteditemkindindex}"/>

    </Grid>
</UserControl>
```

以 Inquiry Attribute Definition 為例

`Inquiry_Attribute_Definition.xaml`
在原本 `<Grid>` 位置改以下code 並加入 `xmlns:view="clr-namespace:ares.client.module.View"`
```xaml
<Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="100"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <view:GridPager Grid.Row="1"
                x:Name="GridPagerViewControl" 
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
        </Grid>
```

`Inquiry_Attribute_Definition.xaml.cs` 建立column (客製化每個頁面的column)
需要import `using Infragistics.Controls.Grids;`
```c#
private void generate_columns()
        {
            GridPagerViewControl.TestDataGrid1.Columns.Add(new TextColumn()
            {
                Key = "AttrId",
                HeaderText = "Attr ID"
            });
            GridPagerViewControl.TestDataGrid1.Columns.Add(new TextColumn()
            {
                Key = "CateId",
                HeaderText = "Cate ID"
            });
            GridPagerViewControl.TestDataGrid1.Columns.Add(new TextColumn()
            {
                Key = "AttrName",
                HeaderText = "Attr Name"
            });
            GridPagerViewControl.TestDataGrid1.Columns.Add(new TextColumn()
            {
                Key = "TextData",
                HeaderText = "Text Data"
            });
            GridPagerViewControl.TestDataGrid1.Columns.Add(new TextColumn()
            {
                Key = "Description",
                HeaderText = "Description"
            });
        }
```
Initialize時記得加入 `generate_columns();`


Viewmodel:
```c#
using System.Collections.Generic;
```

`public class Inquiry_Attribute_Definition_VM : ViewModelBase` 中加入

```c#
public class Inquiry_Attribute_Definition_VM : ViewModelBase
    {
        public List<int> itemkind { get; set; }
        public int selecteditemkind { get; set; }
        public int selecteditemkindindex { get; set; }
    }
```

`public Inquiry_Attribute_Definition_VM()` 中加入
```c#
        public Inquiry_Attribute_Definition_VM(IUser user, IApplicationFactory applicationFactory, ISampleService proxy)
            : base(user, applicationFactory)
        {
            itemkind = new List<int> {10, 20, 30, 40, 50};
            selecteditemkindindex = -1;
        }
```
