Views: 0
官方沒這個工具,我反映過了,很多時候BPM只有作為ERP上的合約簽核使用而已,ERP修改合約資料後,BPM就需要退回+更新資料+從申請者重送,一等一官方本身有退回的程序,但改完資料後沒有「重送」的API,這篇內容是我土炮一個相關功能
已知問題
- 文章標題要自己再更新一次,系統不會更新
- 退回後如果是自由流程(我其實搞不清楚這啥用途),基本上會送出失敗
- 我目前只有測試v27跟v28 其他版本能不能用就自求多福…
程式碼
廢話不多…說直接給大家程式碼
自己移植到需要的部分
我是放在CDS/Tools/BPM_ReturnSite.aspx
前端 BPM_ReturnSite.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Master/DefaultMasterPage.master" AutoEventWireup="true" CodeFile="BPM_ReturnSite.aspx.cs" Inherits="CDS_Tools_BPM_ReturnSite" %>
<%@ Register TagPrefix="Fast" Namespace="Ede.Uof.Utility.Component" Assembly="Ede.Uof.Utility.Component.Grid" %>
<%@ Import Namespace="Ede.Uof.EIP.SystemInfo" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:UpdatePanel runat="server" ID="Udp1">
<ContentTemplate>
<asp:HiddenField runat="server" ID="hfLastSiteId" />
<table class="PopTable">
<tr>
<td>Current.UserGUID 目前登入者GUID</td>
<td><%= Current.UserGUID %></td>
</tr>
<tr>
<td>Current.User.Name 目前登入者名稱</td>
<td><%= Current.User.Name %></td>
</tr>
<tr>
<td>
DOC_NBR
</td>
<td>
<asp:TextBox runat="server" ID="txtDocNbr"></asp:TextBox>
<asp:Button runat="server" ID="btnFindTaskId" Text="Doc Nbr 查詢Task ID" OnClick="btnFindTaskId_OnClick"/>
<asp:Label runat="server" ID="lblMsgFindTaskID" Text="" ForeColor="blue"></asp:Label>
</td>
</tr>
<tr>
<td>TASK ID</td>
<td>
<asp:TextBox runat="server" ID="txtTaskID"></asp:TextBox></td>
</tr>
<tr>
<td>Comment 退回申請者要傳送的訊息
</td>
<td>
<asp:TextBox runat="server" ID="txtComment" Rows="3" TextMode="MultiLine"></asp:TextBox></td>
</tr>
<tr>
<td></td>
<td>
<asp:Button runat="server" ID="btnSetReturn" OnClick="btnSetReturn_OnClick" Text="退回申請者" /></td>
<asp:Label runat="server" ID="lbMessage" ForeColor="Red"></asp:Label>
</tr>
<tr>
<tr>
<td>Comment-重送</td>
<td>
<asp:TextBox runat="server" ID="txtCommentReApply" Rows="3" TextMode="MultiLine"></asp:TextBox></td>
</tr>
<td></td>
<td>
<asp:Button runat="server" ID="btnReApply" Text="重送" OnClick="btnReApply_OnClick"/>
<asp:Label runat="server" ID="lbMessageReApply" Text="" ForeColor="Green" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
後端 BPM_ReturnSite.aspx.cs
using Ede.Uof.EIP.Organization.Util;
using Ede.Uof.EIP.SystemInfo;
using Ede.Uof.WKF.Data;
using Ede.Uof.WKF.Engine;
using Ede.Uof.WKF.Exceptions;
using Ede.Uof.WKF.PersonalBox;
using Ede.Uof.WKF.Utility;
using System;
using System.Data;
public partial class CDS_Tools_BPM_ReturnSite :Ede.Uof.Utility.Page.BasePage
{
private string AddWKFSignerInfoList(UserSet userSet)
{
string userSetXml = string.Empty;
if (userSet != null)
{
for (int i = 0; i <= userSet.Items.Count - 1; i++)
{
UserSetUser userSetUser = (UserSetUser)userSet.Items[i];
if (userSetUser.WKFSignerInfoList.Count <= 0)
{
var ebUser = userSetUser.EBUsers[0];
WKFSignerInfo wkfSignerInfo = new WKFSignerInfo(
ebUser.GroupID,
ebUser.GroupName,
string.Empty,
string.Empty,
string.Empty,
string.Empty
);
userSetUser.WKFSignerInfoList.Add(wkfSignerInfo);
}
}
userSetXml = userSet.GetXML();
}
return userSetXml;
}
protected void Page_Load(object sender, EventArgs e)
{
}
private readonly string _connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["connectionstring"].ConnectionString;
/// <summary>
/// 退回申請者
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnSetReturn_OnClick(object sender, EventArgs e)
{
lbMessage.Text = "";
var result = GetSiteIDAndNodeSeq(txtTaskID.Text);
//如果沒有資料就不執行
if (result.SiteID == "無資料" || result.NodeSeq == "無資料")
{
lbMessage.Text = "查無資料,請確認TaskID是否正確";
return;
}
//退回申請者
try
{
//一定要有備註才能退回申請者
UpdateComment(txtComment.Text, txtTaskID.Text);
var rUCO = new ReturnSignUCO();
rUCO.ReturnToApplicant(txtTaskID.Text, result.SiteID, Convert.ToInt32(result.NodeSeq), Current.UserGUID, Convert.ToBoolean(false), Source.PCBatch.ToString());
lbMessage.Text = "退簽完成";
}
catch (Exception exception)
{
lbMessage.Text = $"退簽失敗 {exception}";
}
}
private void UpdateComment(string message , string TASKID)
{
message = (message ?? "").Replace("\r\n", "\n").Replace("\n", "\r\n");
string sql = @"UPDATE [TB_WKF_TASK_NODE] SET COMMENT = @COMMENT WHERE TASK_ID = @TASKID
AND FINISH_TIME IS NULL";
//sql
using (var conn = new System.Data.SqlClient.SqlConnection(this._connectionString))
{
conn.Open();
using (var cmd = new System.Data.SqlClient.SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@COMMENT", message);
cmd.Parameters.AddWithValue("@TASKID", TASKID);
cmd.ExecuteNonQuery();
}
}
}
private (string SiteID, string NodeSeq) GetSiteIDAndNodeSeq(string taskID)
{
string sql = @"
SELECT SITE_ID, NODE_SEQ
FROM TB_WKF_TASK_NODE
WHERE TASK_ID = @TASKID
AND FINISH_TIME IS NULL
";
DataTable dt = new DataTable();
using (var conn = new System.Data.SqlClient.SqlConnection(this._connectionString))
using (var cmd = new System.Data.SqlClient.SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@TASKID", taskID);
using (var da = new System.Data.SqlClient.SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
if (dt.Rows.Count > 0)
{
return (dt.Rows[0]["SITE_ID"].ToString(), dt.Rows[0]["NODE_SEQ"].ToString());
}
return ("無資料", "無資料");
}
protected void btnFindTaskId_OnClick(object sender, EventArgs e)
{
lblMsgFindTaskID.Text = "";
txtTaskID.Text = "";
//根據單號找TaskID
string sql = @"
SELECT TASK_ID
FROM TB_WKF_TASK
WHERE DOC_NBR = @DOC_NBR";
DataTable dt = new DataTable();
using (var conn = new System.Data.SqlClient.SqlConnection(this._connectionString))
using (var cmd = new System.Data.SqlClient.SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@DOC_NBR", txtDocNbr.Text);
using (var da = new System.Data.SqlClient.SqlDataAdapter(cmd))
{
da.Fill(dt);
}
if (dt.Rows.Count > 0)
{
txtTaskID.Text = dt.Rows[0]["TASK_ID"].ToString();
lblMsgFindTaskID.Text = "查詢成功";
}
else
{
lblMsgFindTaskID.Text = "查無資料,請確認單號是否正確";
}
}
}
/// <summary>
/// 檢查是否已經退回使用者
/// </summary>
/// <returns></returns>
public bool IsReturnUser(string Task_ID)
{
string sql = @"
SELECT TOP (1) [TASK_ID]
,[TASK_STATUS]
FROM [TB_WKF_TASK]
where TASK_ID = @TASK_ID;
";
using (var conn = new System.Data.SqlClient.SqlConnection(this._connectionString))
using (var cmd = new System.Data.SqlClient.SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@TASK_ID", Task_ID);
conn.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
//這個旗標要4才是退回使用者,其他狀態都不是
return reader["TASK_STATUS"].ToString() == "4";
}
}
}
return false;
}
/// <summary>
/// 進行退簽動作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnReApply_OnClick(object sender, EventArgs e)
{
lbMessageReApply.Text = "";
try
{
string taskId = txtTaskID.Text.Trim();
if (string.IsNullOrWhiteSpace(taskId))
{
lbMessageReApply.Text = "請輸入 TaskID";
return;
}
UpdateComment(txtCommentReApply.Text, taskId);
string newTaskId = ReApplyReturnedTaskInternal(taskId, Current.UserGUID);
lbMessageReApply.Text = $"重送成功,TaskID={newTaskId}";
}
catch (NoCondBranchSiteException ex)
{
lbMessageReApply.Text = $"重送失敗:找不到條件分支站點。{ex.Message}";
}
catch (NoJobTitleException ex)
{
lbMessageReApply.Text = $"重送失敗:申請者無職級。{ex.Message}";
}
catch (MustSetCustSiteException ex)
{
lbMessageReApply.Text = $"重送失敗:需指定自訂流程站點。{ex.Message}";
}
catch (MustSetGroupSiteException ex)
{
lbMessageReApply.Text = $"重送失敗:需指定自選流程站點。{ex.Message}";
}
catch (CallExternalDllFlowException ex)
{
lbMessageReApply.Text = $"重送失敗:外部流程 DLL 例外。{ex.Message}";
}
catch (AccountNoFoundException ex)
{
lbMessageReApply.Text = $"重送失敗:找不到帳號。{ex.Message}";
}
catch (ExternalDllFormatErrorException ex)
{
lbMessageReApply.Text = $"重送失敗:外部 DLL 格式錯誤。{ex.Message}";
}
catch (Exception ex)
{
lbMessageReApply.Text = $"重送失敗:{ex}";
}
}
/// <summary>
/// 重送已退簽使用者的TaskID
/// </summary>
/// <param name="taskId">退簽的TaskID</param>
/// <param name="operatorUserGuid">重送者</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private string ReApplyReturnedTaskInternal(string taskId, string operatorUserGuid)
{
if (!IsReturnUser(taskId))
{
throw new Exception("此申請單尚未退回使用者,無法重送");
}
Task task = new Task(taskId);
if (task == null)
throw new Exception("找不到 Task");
if (task.Applicant == null)
throw new Exception("找不到 Applicant");
if (task.CurrentSite == null)
throw new Exception("找不到 CurrentSite");
// ★ 關鍵:先把目前 Task 轉成重送用暫存 Script
var returnUco = new ReturnSignUCO();
returnUco.TransferTaskToTempScript(taskId);
// ★ 可選:確認 script 真的存在
ScriptUCO scriptUCO = new ScriptUCO();
DataTable dtFormVersion = scriptUCO.GetFormVersionInfo(taskId);
if (dtFormVersion == null || dtFormVersion.Rows.Count == 0)
{
throw new Exception("TransferTaskToTempScript 後仍找不到 Script/FormVersion 資料");
}
DefinedTask defTask = DefinedTask.GetVirtualDefinedTask(
taskId,
task.Applicant.GroupId,
task.Applicant.JobTitleId
);
if (defTask == null)
{
throw new Exception("GetVirtualDefinedTask 回傳 null(已做 TransferTaskToTempScript)");
}
if (defTask.CurrentDocument != null &&
defTask.CurrentDocument.AllowSkipped &&
defTask.BeSkippedSite != null &&
defTask.BeSkippedSite.Count > 0)
{
throw new Exception("此單含略過站點,暫不支援");
}
if (defTask.DefinedTaskSiteList != null && defTask.DefinedTaskSiteList.Count > 0)
{
throw new Exception("此單為平行站點流程,暫不支援");
}
if (defTask.NextDefinedTaskSite == null)
{
throw new Exception("找不到下一站點,可能已到流程末端");
}
DefinedTaskSite nextSite = defTask.NextDefinedTaskSite;
if (nextSite.IsCustSite)
throw new Exception("下一站為自訂流程站點,暫不支援");
if (nextSite.IsExternalSite)
throw new Exception("下一站為外部站點,暫不支援");
if (nextSite.SiteKind == DefinedTaskSiteKind.AssignAbleSite)
throw new Exception("下一站為指定式站點,暫不支援");
if (nextSite.SiteKind == DefinedTaskSiteKind.FreeSite)
throw new Exception("下一站為自由流程站點,暫不支援");
TempDefinedSiteDataSet tempDs = defTask.TempDefSiteInfoDs;
if (tempDs == null ||
tempDs.TB_WKF_TASK_SITE_TEMP == null ||
tempDs.TB_WKF_TASK_SITE_TEMP.Rows.Count == 0)
{
throw new Exception("TempDefinedSiteDataSet 為空");
}
var row = (TempDefinedSiteDataSet.TB_WKF_TASK_SITE_TEMPRow)tempDs.TB_WKF_TASK_SITE_TEMP.Rows[0];
row.IS_PREADDITIONAL_SITE = nextSite.IsPreAdditionalSite;
row.PREADDITIONAL_FLOW = nextSite.PreAdditionalFlow ?? "";
row.CUST_TYPE = 0;
row.IS_MASTER_SITE = row.IsSRC_PARENT_SITE_IDNull();
row.IS_END_BY_APPLICANT = false;
row.IS_SAVE_SCRIPT = false;
row.TIMEOUT_COUNT = nextSite.TimeOutCont;
int cycleHours = 0;
int.TryParse(new TaskUtilityUCO().GetCycleAlertHours(task.FormVersionId, nextSite), out cycleHours);
row.CYCLE_HOURS = cycleHours;
row.TIMEOUT_SEND_COUNT = nextSite.TimeOutSendCount;
row.SIGN_TYPE = (int)nextSite.SignType;
row.SIGNER_USER_SET = AddWKFSignerInfoList(nextSite.AllSignerUserSet);
row.ALERTER_USER_SET = nextSite.AllAlerterUserSet == null
? new UserSet().GetXML()
: nextSite.AllAlerterUserSet.GetXML();
row.ADDTIONAL_FLOW_ID = defTask.AddtionalFlowId ?? "";
row.SOURCE = Source.PC.ToString();
DefinedTask actualTask = new DefinedTask(taskId, task.CurrentSite.SiteId, 0);
actualTask.ReApply(tempDs, Source.PC, operatorUserGuid);
EBUser ub;
return actualTask.TaskId;
}
}
0 Comments