起步软件技术论坛-X3

 找回密码
 立即注册
搜索
楼主: danceyoung

[结贴]代码启动流程 流程事务和Query事务

[复制链接]
 楼主| 发表于 2009-9-15 13:37:06 | 显示全部楼层
不好意思,上午有点事情不在公司。
谢谢你的回帖。
这个功能的代码也就这些了。按钮的单击事件是代码启动流程,并要修改业务单据的sql语句。
在功能窗体上放了一个flowbroker1,写了beforeflowout事件是为了代码设置执行者和不显示流程窗体。那我该怎么写呢。请教了,对x3的流程 底层的实现不甚了解啊。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-15 13:39:28 | 显示全部楼层
就是想实现流程和业务单据的更改在一个事务中。
谢谢。
回复 支持 反对

使用道具 举报

发表于 2009-9-15 13:41:49 | 显示全部楼层
流程中的事务请楼主看下下面链接的3楼
http://bbs.justep.com/forum.php?mod=viewthread&tid=19618
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-15 13:51:55 | 显示全部楼层
好的  这个我看过了。
如果按照alang的共享:在任何一个事件处理程序中,如果出错,都会造成流转不成功。
也就是说  ,现在我把更改业务单据的sql(这个可以参考alang分享的代码把query的事务和流程的事务连接一下)写在功能(代码启动流程的功能)上的flowBroker1的beforeflowOut的事件中,就可以达到query和流程的事务同步,是吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-15 20:33:00 | 显示全部楼层
如果在具体的业务流程的某个功能,流程的事务和query的事务按照alang的分享的代码是可以实现的。
但是 这个功能是和流程没有关系的单独功能,作为服务来运行。就是实现 根据任务信息代码自动启动流程,并控制流程和业务单据事务同步。
下面是功能的代码,在按钮的事件中写事务显然不行的,我在flowBroker1的beforeflowOut事件中写了事务。具体报错信息如下。
我这样的实现代码启动流程,事务能否控制,要是不能,我就折腾这个,想其他办法了。
谢谢,请赐教。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-15 20:34:20 | 显示全部楼层
unit mainform;

interface

uses
  Business.System, Business.Forms, Business.Model.Flow, Business.Data, Business.Model,
  Business.Model.Flow, Business.Model.Org;

type
  Tmainform = class(TForm)
    Button1: TButton;
    FuncBroker1: TFuncBroker;
    InfoBroker1: TInfoBroker;
    DataSetBroker1: TDataSetBroker;
    FlowBroker1: TFlowBroker;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure FlowBroker1BeforeFlowOut(Sender: TObject; Command: TFlowOutCommand);
    procedure Timer1Timer(Sender: TObject);
    procedure BizFormCreate(Sender: TObject);
  private
    {private declarations}
    queryTask:TQuery;
    agentToUnit,agentToDept,agentToPositon,agentToPsn:string;
    flowId,bfUpdate:string;
    procedure DoGetFlowGUIDs(const AFlowID: string; AFlowGUIDs: TStrings);
    function getAgentToUnitiInfo(guid:String):TDataSet;
    function setXTaskStatus(query:TQuery;guid:string):boolean;
    function getAppResult(query:Tquery;relaId:string):TDataSet;
    function updateBizDoc(query:Tquery;sql:string):boolean;
  public
    {public declarations}
  end;

implementation

function TMainForm.updateBizDoc(query:Tquery;sql:string):boolean;
begin
    query.Close;
    query.CommandText:=sql;
    query.Execute;
end;

function TMainForm.getAppResult(query:Tquery;relaId:string):TDataSet;
begin
    query.Close;
    query.CommandText:='select EMApprovedDate,EMIsAgree,EMAppOpin from erp_task where relaID='''+relaId+'''';
    query.Open;
    result:=query;
end;

function TMainForm.setXTaskStatus(query:TQuery;guid:string):boolean;
//var
   //query:Tquery;
begin
   try
       //query:=Tquery.Create(nil);
       //query.ConnectionString:= 'DATABASEURL=Biz:\CPSAPP\CPSDB.DATABASE';
       query.close;
       query.CommandText:='update ERP_TASK set status=''1'' where relaid='''+guid+'''';
       query.Execute;
   finally

   end;
end;

function TMainForm.getAgentToUnitiInfo(guid:String):TDataSet;
var
   query:Tquery;
begin
   try
       query:=Tquery.Create(nil);
       query.ConnectionString:= 'DATABASEURL=Biz:\CPSAPP\CPSDB.DATABASE';
       query.CommandText:='select * from PROCAGENT_UNIT where guid='''+guid+'''';
       query.Open;
       result:=query;
   finally

   end;
end;

procedure TMainForm.DoGetFlowGUIDs(const AFlowID: string; AFlowGUIDs: TStrings);
var
  Query : tQuery ;

begin
  if Query=nil then
     Query := tQuery.Create(nil)  ;
  Query.ConnectionString := 'DATABASEURL=Biz:\SYSTEM\SYSTEM.DATABASE';
  Query.CommandText := 'SELECT FFLOWGUID FROM TFLOWID WHERE FID = '+ ''''+AFlowID+'''' ;
  Query.Open;
  while not Query.Eof do
  begin
    AFlowGUIDs.Add(Query.FieldByName('FFLOWGUID').AsString);
    Query.Next;
  end;
  Query.Close;
end;
procedure Tmainform.Button1Click(Sender: TObject);
var
  lTaskParam: TLoadTaskParam;
  lFlowParam: TLoadFlowParam;
  lTasks: TTasks;
  lDataSet : TDataSet;
  lFunc: TFunc;
  lFlowControl: TFlowControl;
  FlowBroker:TFlowBroker;
  lOrgURL:TOrgURL;
  ds,ds1:Tdataset;
  queryFitTask:TQuery;
  setXTaskStatusQry,updateBizDocApp,getEMAppRslt: TQuery;
  lConn: TConnection;
  updateSql:string;
begin
  lDataSet := DataSetBroker1.DataSet;
  lFlowParam := TLoadFlowParam.Create;
  lTaskParam := TLoadTaskParam.Create;
  lTasks := TTasks.Create;
  if setXTaskStatusQry =  nil then
    setXTaskStatusQry:=TQuery.create(nil);
  if lConn = nil then
    lConn:=TConnection.Create(nil);
  if queryTask=nil then
    queryTask:=TQuery.Create(nil);
  if queryFitTask= nil then
    queryFitTask:=TQuery.Create(nil);
  if updateBizDocApp = nil then
     updateBizDocApp:=Tquery.Create(nil);
  if getEMAppRslt = nil then
     getEMAppRslt:=Tquery.Create(nil);
  try
    queryTask.Close;
    queryTask.ConnectionString:='DATABASEURL=Biz:\CPSAPP\CPSDB.DATABASE';
    queryFitTask.Close;
    queryFitTask.ConnectionString:='DATABASEURL=Biz:\CPSAPP\CPSDB.DATABASE';
    //查询未处理的任务
    queryTask.CommandText:='select * from emailtask where guid in (select relaid from erp_task where status=''0'' ) ';
    queryTask.Open;
    queryTask.First;
    while not queryTask.Eof do
    begin
        //根据流程字段,找到对应的流程Guid值
        flowId:=queryTask.FieldByName('flowfield').AsString;
        DoGetFlowGUIDs(flowId, lFlowParam.GUIDs);
        lTaskParam.States := [TTaskState.tsStarted, TTaskState.tsProcessing, TTaskState.tsWaiting];
        //以给定的条件查询任务(这里给定的条件由lFlowParam给出,根据流程Guid值查询,lTaskParam条件是按照任务状态,只查询出需要处理的任务)
        lFlowParam.ProcURLs.Add(queryTask.FieldByName('propath').AsString);
        //lTaskParam.Receivers.Add(lOrgURL);
        Flow.FlowEngine.GetTasks(lFlowParam, lTaskParam, lTasks);
        //判断在X3任务表取出的任务 是否是emailtask表的任务的后续任务
        queryFitTask.Close;
        queryFitTask.CommandText:='select fguid from ttask where FPREVGUID='''+queryTask.FieldByName('taskguid').asstring+'''';
        queryFitTask.Open;
        if lTasks[0].GUID =queryFitTask.FieldByName('fguid').AsString then
        begin
                //lFunc := SystemCore.TSystemCore.FuncManager.RunTask(SystemCore.TSystemCore.Operator.Positions[0], lTasks[0]);
                lFunc := SystemCore.TSystemCore.FuncManager.RunTask(self.Context, lTasks[0]);
              {//如果需要自动流转,则需要下面的代码vvvvvvvvvvvvvv
                lFlowControl := lFunc.Context.GetParentContext(BizSys.IL_FLOW).Owner as TFlowControl;
                lFlowBroker:=TFlowBroker.create(lFunc);
                //lFlowBroker.OnCreateFlowOutFlowTasks:=FlowBroker1BeforeFlowOut;
                lFlowControl.FlowOut(nil);
              //如果需要自动流转,则需要下面的代码^^^^^^^^^^^^^^ }
                //创建一个流程代理,对流程代理的事件赋值,可以在流程监控中自己控制流程流转时是否显示流转对话框,根据业务数据确定下一个环节执行者等
                lConn.ConnectionString:= 'DATABASEURL=Biz:\CPSAPP\CPSDB.DATABASE';
                setXTaskStatusQry.Connection:=lConn;
                getEMAppRslt.Connection:=lConn;
                updateBizDocApp.Connection:=lConn;
              //得到处理人的信息
              ds:=getAgentToUnitiInfo(queryTask.FieldByName('agenttoprounit').AsString);
              //得到邮件审批结果的信息
              ds1:=getAppResult(getEMAppRslt,queryTask.FieldByName('guid').AsString);
              //agentToUnit,agentToDept,agentToPositon,agentToPsn
              agentToUnit:=ds.FieldByName('atounit').AsString;
              agentToDept:=ds.FieldByName('prodept').AsString;
              agentToPositon:=ds.FieldByName('proposition').AsString;
              agentToPsn:=ds.FieldByName('proedby').AsString;
              //流转前先把是否同意赋值,要不下面流转:就起不到自动流转的效果了。
              bfUpdate:=queryTask.FieldByName('updateSql').AsString+''''+ds1.FieldByName('EMIsAgree').AsString+''''
                                   +' where guid='''+flowId+'''' ;
              //---
                lFlowControl := lFunc.Context.GetParentContext(BizSys.IL_FLOW).Owner as TFlowControl;
                FlowBroker := TFlowBroker.Create(lFunc);
                FlowBroker.OnCreateFlowOutFlowTasks:=FlowBroker1BeforeFlowOut;
               // raise exception.Create('the exception is running...');
                //更新表的事务和流程事务同步
                //lConn.ConnectionString:= 'DATABASEURL=Biz:\CPSAPP\CPSDB.DATABASE';
                //setXTaskStatusQry.Connection:=lConn;
                //getEMAppRslt.Connection:=lConn;
                //updateBizDocApp.Connection:=lConn;
                //在流程控制中,注册自己创建的流程代理
                lFlowControl.RegisterFlowBroker(FlowBroker);
                lFlowControl.FlowOut(nil);
                lFlowControl.UnRegisterFlowBroker(FlowBroker);
                //改erp_task表的状态为已处理
                setXTaskStatus(setXTaskStatusQry,queryTask.FieldByName('guid').AsString);
                //更改业务单据的审批者信息    更改的字段从emailtask表取,更新的值从erp_task表取
                //ds1:=getAppResult(getEMAppRslt,queryTask.FieldByName('guid').AsString);
                updateSql:=queryTask.FieldByName('updateSql').AsString+''''+ds1.FieldByName('EMIsAgree').AsString+''''
                           +', '+queryTask.FieldByName('appDateField').AsString+
                           '=(select emapproveddate from erp_task where relaid='''+queryTask.FieldByName('guid').AsString+''')'
                           +', '+queryTask.FieldByName('appByField').AsString+'='''+queryTask.FieldByName('EMApprovedby').AsString+''''
                           +', '+queryTask.FieldByName('appOpinField').AsString+'='''+ds1.FieldByName('EMAppOpin').AsString+''''
                           +' where guid='''+flowId+'''' ;
                updateBizDoc(updateBizDocApp,updateSql)
        end;

        queryTask.Next;
    end;
  finally
    lFlowParam.Free;
    lTaskParam.Free;
    lTasks.Free;
  end;

end;


procedure Tmainform.FlowBroker1BeforeFlowOut(Sender: TObject; Command: TFlowOutCommand);
var
   lFlowTask:TFlowTask;
   setApproRslt:TQuery;
   lConn:TConnection;
begin
     if lConn =  nil then lConn:=TConnection.Create(nil);
     if setApproRslt = nil then setApproRslt:=TQuery.Create(nil);
     lConn.ConnectionString:= 'DATABASEURL=Biz:\CPSAPP\CPSDB.DATABASE';
     lConn.Transaction:=flowBroker1.flowcontrol.FlowManager.Transaction;
     setApproRslt.Connection:=lConn;
     //流转前更改业务单据的是否同意
     setApproRslt.CommandText:=bfUpdate;
     setApproRslt.Execute;
     lFlowTask:=Command.FlowTasks.FindFlowTask(agentToUnit);
     lFlowTask.Executors.Clear;
     lFlowTask.Executors.Add(agentToDept,agentToPositon,agentToPsn);
     command.UserConfirm:=false;

end;

procedure Tmainform.Timer1Timer(Sender: TObject);
begin
    self.Timer1.Interval:=30*1000;
    jsdialogs.ShowMsg('','');
end;

procedure Tmainform.BizFormCreate(Sender: TObject);
begin
     self.Timer1.Enabled:=true;
end;

end.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-15 20:36:25 | 显示全部楼层
错误信息图

2009-09-15_203526.png

20.8 KB, 下载次数: 252

回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-15 20:38:01 | 显示全部楼层
代码的主要事件就是button1OnClick()和flowBroker1BeforeFlowOutI()
回复 支持 反对

使用道具 举报

发表于 2009-9-16 08:54:38 | 显示全部楼层
尝试用command那个参数获取事务对象
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-16 09:11:46 | 显示全部楼层
好  谢谢lee。正在测试中。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-17 06:58 , Processed in 0.043042 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表