/// <summary>
        /// Cập nhật quy trình theo bước<para/>
        /// Quy trình kết thúc khi next=-1
        /// https://dpscomvn.visualstudio.com/Webcore%20version%202/_workitems/edit/16344/
        /// </summary>
        /// <param name="IdStep"></param>
        /// <param name="Next"></param>
        /// <param name="UserID"></param>
        /// <param name="note"></param>
        /// <returns></returns>
        public bool Update(int IdStep, int Next, long UserID, string note, Boolean IsComeBack = false)
        {
            SqlConditions cond = new SqlConditions();

            cond.Add(new SqlCondition("Id", Id));
            cond.Add(new SqlCondition("IdStep", IdStep));
            cond.Add(new SqlCondition("Next", Next));
            cond.Add(new SqlCondition("Passed", 0));
            cond.Add(new SqlCondition("IsComeBack", IsComeBack));
            string sql = @"select * from DP_Process 
where Id = @Id and IdStep=@IdStep  ";

            sql += " select IdRow from DP_Process p where Id = @Id and IdStep=@IdStep and Next=@Next  and IsComeBackPro = @IsComeBack and (select count(*) from DP_Process_Detail d where p.IdRow=d.IdProcess and Checked=1 and Passed=0)=0";
            sql += " select * from Tbl_PhanAnhGopY where IsDel=0 and Id=@Id";
            DataSet ds = cnn.CreateDataSet(sql, cond);

            if (ds == null)
            {
                Error = "Có gì đó không đúng, vui lòng thử lại sau";
                return(false);
            }
            if (ds.Tables[2] == null || ds.Tables[2].Rows.Count == 0)
            {
                Error = "Phản ánh không tồn tại";
                return(false);
            }
            if (ds.Tables[0] == null || ds.Tables[0].Rows.Count == 0 || ds.Tables[1] == null || ds.Tables[1].Rows.Count == 0)
            {
                Error = "Không tìm thấy bước xử lý hoặc bước xử lý đã được thực hiện";
                return(false);
            }
            DateTime  now = DateTime.Now;
            DataTable dt  = ds.Tables[0];

            foreach (DataRow dr in dt.Rows)
            {
                string idProcess = dr["IdRow"].ToString();
                //Đánh dấu đã xử lý các DP_Process_Detail này
                Hashtable valPassed = new Hashtable();
                valPassed.Add("Passed", 1);

                if (IdLS == 0)
                {
                    valPassed.Add("IdLS", DBNull.Value);
                }
                else
                {
                    valPassed.Add("IdLS", IdLS);
                }
                valPassed.Add("CheckDate", now);
                cnn.Update(valPassed, new SqlConditions()
                {
                    { "IdProcess", idProcess }, { "Passed", 0 }
                }, "DP_Process_Detail");
            }
            ;
            //cập nhật checker cho process này vào bảng DP_Process_Detail
            Hashtable val = new Hashtable();

            val.Add("Checked", 1);
            val.Add("CheckNote", note);
            cnn.Update(val, new SqlConditions()
            {
                { "IdProcess", ds.Tables[1].Rows[0][0].ToString() }, { "Checker", UserID }
            }, "DP_Process_Detail");

            //tìm checkers tiếp theo khi chưa hoàn tất
            if (Next != -1)
            {
                List <string> lstUserPos = new List <string>();
                string        lstUser    = "";
                sql = "exec sp_FindXuLyTiepTheo_Checker @Id ,@IdStep ,@Next,@IsComeBack ";
                DataSet dsNext = cnn.CreateDataSet(sql, new SqlConditions {
                    { "Id", Id }, { "IdStep", IdStep }, { "Next", Next }, { "IsComeBack", IsComeBack }
                });

                DataTable dtNext = dsNext.Tables[0];
                foreach (DataRow dr in dtNext.Rows)//1, 3 IdStep=2
                {
                    List <string> lst = GetCheckers(dr["IdStep"].ToString(), dr["Next"].ToString(), Convert.ToBoolean(dr["IsComeBackPro"]));
                    if (!string.IsNullOrEmpty(Error))
                    {
                        return(false);
                    }
                    if (lst.Count > 0 && dr["IdForm"].ToString() != "6")
                    {
                        ///huy thi k can thong bao
                        lstUserPos.AddRange(lst);
                    }

                    foreach (string id in lst)
                    {
                        Hashtable val1 = new Hashtable();
                        val1["IdProcess"] = dr["IdRow"];
                        val1["Checker"]   = id;
                        cnn.Insert(val1, "DP_Process_Detail");
                        if (cnn.LastError != null)
                        {
                            return(false);
                        }
                    }
                }
                if (lstUserPos.Count > 0)
                {
                    lstUserPos = lstUserPos.Distinct().ToList();
                }
                lstUser = string.Join(",", lstUserPos);
                if (string.IsNullOrEmpty(lstUser))
                {
                    string    str58    = @"	select  distinct UserID from Tbl_User_GroupUser gu inner join Dps_UserGroupRoles gr on gu.IdGroupUser=gr.IdGroupUser
                                        inner join Dps_Roles on IdRole = gr.IDGroupRole
                                        inner join DPS_User u on u.UserID = gu.IdUser
										inner join v_QuyenUser qu on qu.IdUser=u.UserID and qu.IdRole=Dps_Roles.IdRole
                                         where Dps_Roles.IdRole = 1084 and Deleted = 0 and u.Active =1 ";
                    DataTable dtUser58 = cnn.CreateDataTable(str58);
                    var       temp     = dtUser58.AsEnumerable().Select(x => x["UserID"].ToString()).ToList();
                    lstUser = string.Join(",", temp);
                }
            }
            return(true);
        }