public static WFManualWorkItem GetWorkItem(string wID) { IWFWorkflowService svc = Common.GetWorkFlowAPI(); string workItemID = wID;// for example, "54A648A0A3004A02981E7F0848820FE7"; WFManualWorkItem workItem = null; try { workItem = svc.GetWorkItem(workItemID); } catch (Exception ex) { } return(workItem); }
static void Main(string[] args) { userNameWithDomain = "ap-fvzlpv2\\agpsvc"; passWord = "******"; AuthHeader = string.Format("Basic " + Base64Encode(string.Format("{0}:{1}", userNameWithDomain, passWord))); try { SetCustomAttribute(); WFManualWorkItem workItemResponse = GetWorkItem("804738002502C7551199AE51BDBC1BEF"); IWFWorkflowService wfService = GetWorkflowService(); WFManualWorkItem wFProcessDefinitions = wfService.GetWorkItem("804738002502C7551199AE51BDBC1BEF"); Console.ReadLine(); } catch (Exception e) { Console.WriteLine("\nException Caught!"); } }
//得到当前步骤的名称 public string getDisplayName(string processInstanceID) { WFManualWorkItem thisNode = getNextNode(processInstanceID); return(thisNode.DisplayName); }
//设定绑定的属性值 public void setValue(string pid, string name, object value) { WFManualWorkItem thisNode = getNextNode(pid); api.SetCustomAttr(thisNode.WorkObjectID, name, value); }
//得倒绑定的属性值 public object getValue(string pid, string name) { WFManualWorkItem thisNode = getNextNode(pid); return(api.GetCustomAttr(thisNode.WorkObjectID, name)); }
//找到下个节点 private string prepareNextNode(string processInstanceID, string lastUserID, int OrganizationUnitID, ref string email) { WFManualWorkItem nextNode = getNextNode(processInstanceID); if (nextNode == null) { return(null); //process finished } else { string participant = ""; string participantEmail = ""; nextNode.UserID = nextNode.UserID.Split('\\')[1].ToString(); //translate participant(防止多个流程角色) string[] ids = nextNode.OriginalUserID.Split('\\')[1].ToString().Split("|".ToCharArray()); for (int i = 0; i < ids.Length; i++) { string uid = string.Empty; string PositionTypeCode = ids[i].ToString(); getUserIDByIdentifier(PositionTypeCode, OrganizationUnitID, ref uid, ref email); //当前角色下找不到人 if (uid == "none") { continue; } else { participant += uid + "&"; participantEmail += email; } } participant = participant.TrimEnd('&'); // update workitem APWorkFlow.NodeStatusDataTable dt = new APWorkFlow.NodeStatusDataTable(); APWorkFlow.NodeStatusRow dr = dt.NewNodeStatusRow(); if (!String.IsNullOrEmpty(participant) && participant != "none") //user found { dr.STATUS = FlowNodeStatus.ASSIGNED; dr.PARTICIPANT = participant; //dr.AcceptChanges(); dt.AddNodeStatusRow(dr); dt.AcceptChanges(); StringWriter sw = new StringWriter(); dt.WriteXml(sw); string clientData = sw.ToString(); System.Collections.ArrayList attrList = new System.Collections.ArrayList(); attrList.Add(new NameValue("UserID", dr.PARTICIPANT));//更新该步骤的userid attrList.Add(new NameValue("CLIENT_DATA", clientData)); NameValue[] attributes = (NameValue[])attrList.ToArray(typeof(NameValue)); api.UpdateWorkItem(nextNode.WorkItemID, attributes); //update email if (!String.IsNullOrEmpty(participantEmail)) { email = participantEmail; } return(dr.PARTICIPANT); } else // 没有找到人员 { dr.STATUS = FlowNodeStatus.ONERROR; dr.PARTICIPANT = "P" + lastUserID + "P"; //dr.ERROR_MSG = "错误代码:Invalid UserId (" + nextNode.ProcInstName + "," + nextNode.OriginalUserID + "," + nextNode.UserID + ")"; dr.ERROR_MSG = "未能找到下一步审批人!"; //dr.AcceptChanges(); dt.AddNodeStatusRow(dr); dt.AcceptChanges(); StringWriter sw = new StringWriter(); dt.WriteXml(sw); string clientData = sw.ToString(); System.Collections.ArrayList attrList = new System.Collections.ArrayList(); attrList.Add(new NameValue("UserID", dr.PARTICIPANT)); attrList.Add(new NameValue("CLIENT_DATA", clientData)); NameValue[] attributes = (NameValue[])attrList.ToArray(typeof(NameValue)); api.UpdateWorkItem(nextNode.WorkItemID, attributes); // sendMail(getUserEmailByID(int.Parse(lastUserID)), "", "您提交的单据发生错误", "单据编号为:" + nextNode.ProcInstName); throw new ApplicationException(dr.ERROR_MSG); } } }
public string approve(bool isApproved, string approvalComment, string userID, string userName, string processInstanceID, string proxyUserName, int OrganizationUnitID, ref string email) { try { if (String.IsNullOrEmpty(processInstanceID)) { throw new Exception("approve - processInstanceID is empty"); } if (String.IsNullOrEmpty(userID)) { throw new Exception("approve - userID is empty"); } if (String.IsNullOrEmpty(userName)) { throw new Exception("approve - userName is empty"); } string where = "WF_MANUAL_WORKITEMS.PROC_INST_ID='" + processInstanceID + "' and WF_MANUAL_WORKITEMS.STATUS in ('" + WFManualWorkItem.ASSIGNED + "','" + WFManualWorkItem.OVERDUE + "','" + WFManualWorkItem.REASSIGNED + "','" + WFManualWorkItem.PSEUDO + "') and CHARINDEX('P" + userID + "P',WF_MANUAL_WORKITEMS.USER_ID)>0"; WFManualWorkItem[] wis = api.QueryWorkListEx(where); if (wis.Length > 0) { WFManualWorkItem wi = wis[0]; APWorkFlow.NodeStatusDataTable dt = new APWorkFlow.NodeStatusDataTable(); StringReader sr = new StringReader(wi.ClientData); dt.ReadXml(sr); APWorkFlow.NodeStatusRow dr = dt[0]; if (String.IsNullOrEmpty(proxyUserName)) { dr.APPROVED_BY = userName; } else { dr.APPROVED_BY = proxyUserName + " 代理 " + userName; } if (String.IsNullOrEmpty(approvalComment)) { dr.COMMENTS = ""; } else { dr.COMMENTS = approvalComment; } dr.COMPLETED_DATE = DateTime.Now.ToString("yyyy-MM-dd HH:mm"); if (isApproved)//若状态为通过 { // 首先判断是否为尝试修复的 if (dr.STATUS.Equals(FlowNodeStatus.ONERROR)) { // recover this node System.Collections.ArrayList attrList = new System.Collections.ArrayList(); attrList.Add(new NameValue("UserID", wi.OriginalUserID)); NameValue[] attributes = (NameValue[])attrList.ToArray(typeof(NameValue)); api.UpdateWorkItem(wi.WorkItemID, attributes); } else { dr.STATUS = FlowNodeStatus.APPROVED;//通过 //dr.AcceptChanges(); dt.AcceptChanges(); StringWriter sw = new StringWriter(); dt.WriteXml(sw); string clientData = sw.ToString(); //将信息写入XML并保存 WFEvent evt = api.CompleteWorkItemEx(wi.WorkItemID, clientData); //完成当前步骤 evt = getFullEvent(evt); if (!String.IsNullOrEmpty(evt.Error)) { throw new Exception("approve - " + evt.Error); } } } else { //直接取消流程 if (dr.STATUS.Equals(FlowNodeStatus.ONERROR)) { dr.COMMENTS = dr.ERROR_MSG; } dr.STATUS = FlowNodeStatus.CANCELLED; //dr.AcceptChanges(); dt.AcceptChanges(); StringWriter sw = new StringWriter(); dt.WriteXml(sw); string clientData = sw.ToString(); ArrayList attrList = new ArrayList(); attrList.Add(new NameValue("CLIENT_DATA", clientData)); NameValue[] nv = (NameValue[])attrList.ToArray(typeof(NameValue)); api.UpdateWorkItem(wi.WorkItemID, nv); WFEvent evt = api.CancelProcInst(processInstanceID); evt = getFullEvent(evt); if (!String.IsNullOrEmpty(evt.Error)) { throw new Exception("approve - " + evt.Error); } } //prepare next node string nextUser = prepareNextNode(processInstanceID, userID, OrganizationUnitID, ref email); //if (!String.IsNullOrEmpty(nextUser) && nextUser == "P" + userID + "P") // 如果下一步包有且只有同一个人就自动审批(后面需要在审批历史里加入自动通过的标识) // return approve(isApproved, approvalComment, userID, userName, processInstanceID, proxyUserName, OrganizationUnitID, ref email); //else return(nextUser); } else { throw new Exception("approve - 用户不能操作当前流程"); } } catch (Exception e) { if (e is ApplicationException) { throw e; } throw new Exception(errorMSGPrefix + e.Message, e); } }
public WFManualWorkItem approvetest(WFManualWorkItem WorkItem, int OrganizationUnitID) { string participant = ""; api.CompleteWorkItem(WorkItem.WorkItemID); WorkItem = getNextNode(WorkItem.ProcInstID); if (WorkItem != null) { string[] ids = WorkItem.OriginalUserID.Split('\\')[1].ToString().Split("|".ToCharArray()); for (int i = 0; i < ids.Length; i++) { string uid = string.Empty; string PositionTypeCode = ids[i].ToString(); string email = ""; getUserIDByIdentifier(PositionTypeCode, OrganizationUnitID, ref uid, ref email); if (uid == "none") { participant = "P27P&"; } else { participant += uid + "&"; } } participant = participant.TrimEnd('&'); System.Collections.ArrayList attrList = new System.Collections.ArrayList(); attrList.Add(new NameValue("UserID", participant));//更新该步骤的userid NameValue[] attributes = (NameValue[])attrList.ToArray(typeof(NameValue)); api.UpdateWorkItem(WorkItem.WorkItemID, attributes); WorkItem = getNextNode(WorkItem.ProcInstID); } return WorkItem; }
private String RenderActivityContent(WorkflowService api, WFBaseProcessInstance pi, string id, WFManualWorkItem[] mwks, WFAutomaticWorkItem[] awks) { string header = // "<DIV style=\"DISPLAY:none;OVERFLOW: auto\">\n" "<TABLE id='popupTable' align=center border=1 bordercolor=lightgrey>\n" + "<TR><td>\n" + "<TABLE style=\"background-color: #ffffcc;font-family: 宋体,Verdana,sans-serif;font-size: 12;Z-INDEX:106\" cellSpacing=\"0\" cellPadding=\"2\" border=\"0\">\n"; string footer = "</TABLE>\n" + "</TD></TR>\n" + "</TABLE>\n"; string content = ""; WFBaseActivityInstance ai = api.GetActivityInst(id); //Retreive process definition and Activity definition string xmlString = api.GetProcDefXml(pi.DefID); WFProcessDefinition processDef = new WFProcessDefinition(); ProcDefXmlParser xmlParser = new ProcDefXmlParser(processDef); xmlParser.Parse(xmlString); IWFActivityDefinition ad = processDef.FindActivityByName(ai.Name); WFManualActivityDefinition activityDef = null; if (ad != null && ad.GetType() == typeof(WFManualActivityDefinition)) { activityDef = (WFManualActivityDefinition)ad; } bool isSub = false; //zhouli ArrayList arrSub = new ArrayList(); ArrayList arrSubName = new ArrayList(); if (ai.Session > 0) { string status = ConvUtil.GetDisplayStatus(pi.Status, ai.Session, ai.TokenPos.Value, ai.Pending, ai.InStack); //zhouli string sql = string.Format(@"SELECT Proc_Inst_ID,Proc_Inst_Name FROM WF_PROC_INSTS WHERE SUPER_PROC_INST_ID='{0}'", pi.ProcInstID); DataTable dtSub = SQLHelper.GetDataTable2(sql); if (dtSub.Rows.Count > 0) { foreach (DataRow dr in dtSub.Rows) { arrSub.Add(dr["Proc_Inst_ID"].ToString()); arrSubName.Add(dr["Proc_Inst_Name"].ToString()); } } status = GetCNStatus(status); content += ConstructRow(status, ""); content += ConstructRow(null, null); if (mwks == null || mwks.Length == 0) { content += ConstructRow("开始日期:", DTFormat(ai.StartedDate)); if (ai.CompletedDate.Ticks > 0) { content += ConstructRow("完成日期:", DTFormat(ai.CompletedDate)); } if (awks != null) { Hashtable names = GetSubProcInstName(api, awks); string url = null; string procInstName = null; foreach (WFAutomaticWorkItem wk in awks) { procInstName = (string)names[wk.WorkItemID]; url = string.Format("<a href=# onclick=\"parent.showSubProcess('{0}')\">Sub Process '{1}'</a>", wk.WorkItemID, procInstName); content += ConstructRow(string.Format("#{0}", wk.Session), url); } } } //Show Mannual activity information else { ArrayList participantList = new ArrayList(); ArrayList participantStatus = new ArrayList(); //Create a list of participant involved in this activity for (int index = mwks.Length - 1; index >= 0; index--) { if (mwks[index].Status == WFManualWorkItem.ASSIGNED || mwks[index].Status == WFManualWorkItem.OVERDUE || mwks[index].Status == WFManualWorkItem.COMPLETED) { if (!String.IsNullOrEmpty(mwks[index].UserID)) { participantList.Add(mwks[index].UserID); participantStatus.Add(mwks[index].Status); } } } //Show type of activity and participant info if it AgileWork of type process adaptation if (activityDef != null && activityDef.CustomProperties.Contains("Ascentn.AgileWork.Premier.ProcessAdaptation")) { //Get type of the AgileWork string activityType = api.GetCustomAttr(pi.WorkObjectID, id + "_ApprovalType") as string; //Show type of the activity content += ConstructRow(null, null); content += ConstructRow("Activity Type:", activityType); //Add those participant who have not been assgined yet(in case of sequential type) to participantList if (activityType == "Sequential") { string activityProperties = api.GetCustomAttr(pi.WorkObjectID, id + "_ActivityProperties") as string; if (!String.IsNullOrEmpty(activityProperties)) { string[] approverInfoList = activityProperties.Split(';'); //If number of Approver is more than one, only first approver is get assigned //So add the rest approver(who have not been assigned)to the Participant List if (approverInfoList.Length > 1) { for (int i = 1; i < approverInfoList.Length; i++) { string[] userInfoList = approverInfoList[i].Split('|'); string user = userInfoList[0]; if (!String.IsNullOrEmpty(user)) { participantList.Add(user); participantStatus.Add("In Queue"); } } } } } } #region 显示人物列表 //Show participant list for the activity if (participantList.Count > 0) { content += ConstructRow("参与该任务的用户", null); for (int i = 0; i < participantList.Count; i++) { if (participantList[i].ToString().ToLower() != @"dev003\dummy")//zhouli content += ConstructRow(participantList[i] + ":", participantStatus[i]); } } foreach (WFManualWorkItem wk in mwks) { if (content.Length > 0) content += ConstructRow(null, null); if (wk.UserID.ToLower() == @"dev003\dummy") //zhouli { for (int sub = 0; sub < arrSub.Count; sub++) { //content += ConstructRow("子流程", arrSub[sub].ToString()); string url = string.Format("<a href=# onclick=\"parent.showSubProcess('{0}')\">{1}</a>", arrSub[sub].ToString(), arrSubName[sub].ToString()); content += ConstructRow("子流程", url); } } else { content += ConstructRow("会话:", wk.Session); content += ConstructRow("任务:", wk.Name); content += ConstructRow("任务处理人:", GetUserName(wk.UserID)); //zhouli content += ConstructRow("任务接收日期:", DTFormat(wk.AssignedDate)); //content += ConstructRow("过期日期:", DTFormat(wk.DueDate)); if (wk.CompletedDate.Ticks > 0) { content += ConstructRow("完成日期:", DTFormat(wk.CompletedDate)); } content += ConstructRow("状态:", wk.Status); } } #endregion } //Add custom attributes changes during this activity into content content += AddCustomAttribToContent(pi.ProcInstID, ai.StartedDate.ToString("M/d/yyyy H:mm:ss:fff tt"), ai.CompletedDate.ToString("M/d/yyyy H:mm:ss:fff tt")); //Show Process Adaptation Link only when AgileWork is of type Ascentn.AgileWork.Premier.ProcessAdaptation and not completed or cancled if (status != WFBaseActivityInstance.PASSED && status != WFBaseActivityInstance.CANCELLED && activityDef != null && activityDef.CustomProperties.Contains("Ascentn.AgileWork.Premier.ProcessAdaptation")) { // Get Process Adaptation Url from web.config string processAdaptationUrl = (String)ConfigurationManager.AppSettings["ProcessAdaptationUrl"]; string queryString = "?ProcessTemplate=" + pi.DefName + "&ProcessInstance=" + pi.ProcInstID + "&ActiveInstance=" + id; string processAdptationLink = string.Format("<a href=# onclick=\"parent.showProcessAdaptation('{0}')\">Open Process Adaptation</a>", processAdaptationUrl + queryString); //Add process adaptation link to the content content += ConstructRow(null, null); content += ConstructRow(processAdptationLink, null); } } else { content += ConstructRow("信息:", "此步骤还未流转到!"); } return header + content + footer; }