<?php 
/**
	工作流的插件
*/

class flowChajian extends Chajian{

	public $flownum;
	public $table;
	public $rs;
	public $urs;
	public $drs;
	
	public $flowrs;
	public $errormsg;
	public $where;
	public $flowarr;
	
	public function __construct($num)
	{
		parent::__construct();
		
		$this->flownum 		= $num;
		$this->errormsg 	= '';
		$this->where	 	= '';
		$this->initflows();
		$this->initflow();
	}
	
	protected function initflow(){}		//初始化流程加载
	protected function initdachange(){} //初始化数据加载
	protected function flowcheckname(){return '';}
	protected function flowsubmit(){}
	protected function flowcheckjudge(){}
	protected function flownothrough(){}
	protected function flowthrough(){}
	
	private function initflows()
	{
		$this->dbcourse = m('flow_course');
		$this->dblog 	= m('flow_log');
		$this->dbrule 	= m('flow_rule');
		$this->dbadmin 	= m('admin');
		$this->dbwhere 	= m('where');
		$this->dbtodo 	= m('todo');
		
		$this->flowrs	= m('flow_set')->getone("`num`='$this->flownum'");
		if(!$this->flowrs){
			$this->addmsg('流程不存在;');
			return;
		}	
		$this->table		= $this->flowrs['table'];
		$this->flowname		= $this->flowrs['name'];
		$this->setid		= $this->flowrs['id'];
		$this->uidfields	= $this->rock->repempt($this->flowrs['uidfields'], 'uid');
		$this->statusfields	= $this->rock->repempt($this->flowrs['statusfields'], 'status');
		$this->nstatusfields= 'nstatus';
		$this->statusmanfields= 'statusman';
		$this->mdb			= m($this->table);
	}
	
	public function addmsg($msg='')
	{
		$this->errormsg .= $msg;
	}
	
	public function initrecord($id)
	{
		$this->id	= $id;
		$this->rs	= $this->mdb->getone("`id`='$id'");
		if(!$this->rs){
			$this->addmsg('['.$id.']记录不存在;');
			return;
		}
		$this->uid	= $this->rs[$this->uidfields];
		$this->urs	= $this->dbadmin->getone("`id`='$this->uid'");
		if(!$this->urs){
			$this->addmsg('人员不存在;');
			return;
		}
		$this->drs	= $this->db->getone($this->rock->T('dept'), "`id`='".$this->urs['deptid']."'");
		$this->where= "`table`='$this->table' and `mid`='$this->id'";
		$this->initdachange();
	}
	
	/**
		获取流程数组
	*/
	public function getflow()
	{
		$this->flowarr		= array();
		$this->a_tempid		= '0';
		$rsone	= $this->prmatchflow($this->setid);
		if(!$rsone){
			$this->addmsg('匹配不到流程;');
			return;
		}
		$this->getflows($rsone, $this->setid);
		
		foreach($this->flowarr as $k=>$crs){
			$uarr = $this->getcheckname($crs);
			$this->flowarr[$k]['checkid'] 	= $uarr[0];
			$this->flowarr[$k]['checkname'] = $uarr[1];
		}
	}
	
	private function getcheckname($crs)
	{
		$type	= $crs['checktype'];
		$cuid 	= '';
		$name 	= '';
		
		$uarr	= $this->flowcheckname($crs['num']);//额外
		if(is_array($uarr))return $uarr;
		
		if($type=='super'){
			$cuid = $this->urs['superid'];
			$name = $this->urs['superman'];
		}
		if($type=='dept'){
			$cuid = $this->drs['headid'];
			$name = $this->drs['headman'];
		}
		if($type=='user'){
			$cuid = $crs['checktypeid'];
			$name = $crs['checktypename'];
		}
		if($type=='rank'){
			$rank = $crs['checktypename'];
			if(!$this->rock->isempt($rank)){
				$rnurs	= $this->dbadmin->getall("`status`=1 and `ranking`='$rank' order by `sort`");
				foreach($rnurs as $k=>$rns){
					$cuid.=','.$rns['id'].'';
					$name.=','.$rns['name'].'';
				}
				if($cuid != ''){
					$cuid = substr($cuid, 1);
					$name = substr($name, 1);
				}
			}
		}
		$cuid	= $this->rock->repempt($cuid);
		$name	= $this->rock->repempt($name);
		return array($cuid, $name);
	}
	
	private function getflows($rsa, $sid)
	{
		if(!$rsa)return;
		$id		= (int)$rsa['id'];
		$this->a_tempid .= ','.$id.'';
		$type	= $rsa['checktype'];
		
		if( !($type == 'start' || $type =='end'))$this->flowarr[] = $rsa;
		
		$allrs	= $this->dbcourse->getall("`pid`='$id' and `setid`='$sid' and `id` not in($this->a_tempid) order by `sort`");
		$nrs	= false;
		$k1		= 0;
		foreach($allrs as $k=>$srs){
			if($k==0)$nrs = $srs;
			$k1++;
		}
		//多分支要判断条件成立的
		if($k1>1){
			foreach($allrs as $k=>$srs){
				if($this->pandanwhere($srs['id'])){
					$nrs = $srs;
					break;
				}
			}
		}
		if($nrs){
			$this->getflows($nrs, $sid);
		}else{
			$nid = (int)$rsa['nid'];
			if($nid >0 ){
				$tenrs = $this->dbcourse->getone("`id`='$nid' and `setid`='$sid' and `id` not in($this->a_tempid) ");
				if($tenrs)$this->getflows($tenrs, $sid);
			}
		}		
	}
	
	private function pandanwhere($sid)
	{
		$bo 	= false;
		$where  = $this->dbwhere->getstring('flowcourse_'.$sid, 'a.', 'b.');
		if($where != ''){
			$total	= $this->db->rows("`[Q]$this->table` a left join `[Q]admin` b on a.`$this->uidfields`=b.`id`", "a.`id`='$this->id' $where");
			if($this->db->nowerror){
				$this->addmsg('判断条件有错('.$sid.'):'.$this->db->error().';');
			}
			if($total > 0)$bo=true;
		}
		return $bo;
	}

	private function prmatchflow($fsid)
	{
		$rsone	= false;
		$rsone1	= false;
		$rsall	= $this->dbcourse->getall("`setid`='$fsid' and `pid`=0 order by `sort`");
		$utid  	= array();
		$dtid  	= array();
		foreach($rsall as $k=>$rsa){
			$atype	= $rsa['atype'];
			if($this->rock->isempt($atype) || $atype == 'all'){
				$rsone1	= $rsa;
				continue;
			}
			$artid = explode(',', $rsa['atypeid']);
			foreach($artid as $ssid){
				if($ssid=='')continue;
				$fs  = substr($ssid, 0, 1);
				$sid = str_replace('u','', $ssid);
				$sid = str_replace('d','', $sid);
				if($fs=='d'){
					$dtid[$sid]= $rsa;
				}else{
					$utid[$sid]= $rsa;
				}					
			}
		}
		if(isset($utid[$this->uid]))$rsone = $utid[$this->uid];
		if(!$rsone){
			$depath = $this->urs['deptpath'];
			if(!$this->rock->isempt($depath)){
				$depa = explode(',', str_replace(array('[',']'), array('',''), $depath));
				foreach($depa as $depas){
					if(isset($dtid[$depas]))$rsone = $dtid[$depas];
				}
			}
		}
		if(!$rsone)$rsone=$rsone1;
		return $rsone;
	}
	
	/**
		添加到log表里面
	*/
	public function addlog($arr=array())
	{
		$addarr	= array(
			'table'		=> $this->table,
			'mid'		=> $this->id,
			'checkname'	=> $this->adminname, 
			'checkid'	=> $this->adminid, 
			'optdt'		=> $this->rock->now,
			'courseid'	=> '0',
			'status'	=> '1',
			'ip'		=> $this->rock->ip,
			'web'		=> $this->rock->web,
			'modeid'	=> $this->setid
		);
		foreach($arr as $k=>$v)$addarr[$k]=$v;
		$this->dblog->insert($addarr);
		return $this->db->insert_id();
	}
	
	/**
		更新审核信息，和当前审核人
	*/
	private function getrule($upd=false)
	{
		$this->getflow();
		$allcourseid	= '';
		$alluserid		= '';
		$alluser		= ''; 
		$allcheckid		= '';
		$step			= 0;
		$nowcourseid	= 0;
		$nextcourseid	= 0;
		$nowuser		= '';
		$nowuserid		= '';
		$this->nowcoursers	= array();
		$this->nextcoursers	= array();
		$allstep		= count($this->flowarr);
		foreach($this->flowarr as $k=>$ars){
			$temp_nuid		= $ars['checkid'];
			$allcourseid   .= '|'.$ars['id'].'';
			$alluserid     .= '|'.$temp_nuid.'';
			$alluser       .= '|'.$ars['checkname'].'';
			if($temp_nuid == ''){
				$temp_nuid = '-2';
			}
			$toa	= $this->dblog->rows("$this->where and `courseid`>0 and `courseid`='".$ars['id']."' and `status`=1");
			if($toa == 0 && $step == 0 ){
				$step 			= $k+1;
				$nowcourseid	= $ars['id'];
				$nowuserid		= $ars['checkid'];
				$nowuser		= $ars['checkname'];
				$this->nowcoursers	= $ars;
				if($step < $allstep){
					$this->nextcoursers	= $this->flowarr[$k+1];
					$nextcourseid		= $this->nextcoursers['id'];
				}	
			}	
		}
		if($allcourseid != ''){
			$allcourseid	= substr($allcourseid, 1);
			$alluserid		= substr($alluserid, 1);
			$alluser		= substr($alluser, 1);
			$allcheckid		= str_replace('|', ',', $alluserid);
		}
		$nstatus	= (int)$this->dblog->getmou('status', $this->where.' and `courseid`>0 order by id desc'); 	
		$uarr		= array(
			'flowname'		=> $this->flowname,
			'flowid'		=> $this->setid,
			'rulename'		=> $this->urs['name'],
			'allcourseid'	=> $allcourseid,
			'alluserid'		=> $alluserid,
			'alluser'		=> $alluser,
			'allstep'		=> $allstep,
			'step'			=> $step,
			'table'			=> $this->table,
			'mid'			=> $this->id,
			'adddt'			=> $this->rock->now,
			'nowcourseid'	=> $nowcourseid,
			'nextcourseid'	=> $nextcourseid,
			'nowuser'		=> $nowuser,
			'nowuserid'		=> $nowuserid,
			'allcheckid'	=> $allcheckid,
			'nstatus'		=> $nstatus
		);
		if($upd){
			$this->ruleupdate($uarr);
		}
		return $uarr;
	}
	
	private function ruleupdate($uarr)
	{
		$where	= $this->where;
		$allcid	= $uarr['allcheckid'];
		if($allcid=='')$allcid='0';
		$allcids= '['.str_replace(',', '],[', $allcid).']';
		$lora	= $this->dblog->getall("$where and `courseid`>0 group by `checkid`", '`checkid`');
		foreach($lora as $k=>$lors){
			if(!$this->rock->contain($allcids, '['.$lors['checkid'].']')){
				$allcid.=','.$lors['checkid'].'';
			}
		}
		$uarr['allcheckid']	= $allcid;
		$ruid	= $this->dbrule->rows($where);
		if($ruid == 0){
			$where	= '';
		}
		$this->dbrule->record($uarr, $where);
		$urarr	= array(
			'allcheckid'	=> $uarr['allcheckid'],
			'nowcheckid'	=> $uarr['nowuserid'],
			'nowcheckname'	=> $uarr['nowuser']
		);
		$this->mdb->record($urarr, "`id`='$this->id'");
	}
	
	/**
		第一步提交时
		@param 	int 	$lx 	类型：0保存/1提交
		@param 	string 	$sm 	提交说明
		@param 	string 	$fuid 	附件id：80,81
	*/
	public function submit($lx=0, $sm='', $fuid='0')
	{
		$name	= '保存';
		if($lx==1){
			if($this->errormsg != '')return $this->errormsg;
			$name	= '提交';
			$arr	= $this->getrule(true);
			$this->mdb->update('`isturn`=1', "`id`='$this->id'");
		}	
		$this->addlog(array(
			'name'		=> $name,
			'explain'	=> $sm
		));
		if($lx==1){
			$this->nexttodocl($arr['nowuserid']);
			$this->flowsubmit();
		}
		return $name.'成功';
	}
	
	public function addtodo($uid, $msg)
	{
		$this->dbtodo->add($uid, $this->flowname, $msg, array(
			'table' => $this->table,
			'mid'	=> $this->id
		));
	}
	
	/**
		通知处理
	*/
	private function nexttodocl($nuid)
	{
		//$this->dbtodo->delete($this->where." and uid in($nuid)");
		//$this->addtodo($nuid, '您有['.$this->urs['name'].']的['.$this->flowname.']需要审核');
	}
	
	/**
		审核
		@param int 		$zt  	审核状态1同意，2不同意
		@param string 	$sm  	审核说明
		@param int 		$shuid  审核人id，0当前用户
	*/
	public function check($zt, $sm='', $shuid=0)
	{
		$msg		= '';
		$ztfields	= $this->statusfields;
		$this->dbtodo->delete($this->where." and uid='$this->uid'");
		if($this->rs[$ztfields] == 1){
			$msg = '记录已审核完成了';
			return $msg;
		}
		
		$checkid			= $this->adminid;
		$checkname			= $this->adminname;
		if($shuid > 0){
			$tens_rs		= $this->dbadmin->getone("`id`='$shuid'", '`id`,`name`'); 
			$checkid		= $tens_rs['id']; 
			$checkname		= $tens_rs['name']; 
		}
		$checkid			= (int)$checkid;
		if($checkid <= 0){
			$msg = '审核人不存在';
			return $msg;
		}
		if($this->errormsg != ''){
			$msg = $this->errormsg;
			return $msg;
		}	
		
		$arr				= $this->dbrule->getone($this->where);
		$nowuserid			= $arr['nowuserid'];
		if(!$this->rock->contain(','.$nowuserid.',', ','.$checkid.',')){
			$msg='当前审核人是:['.$arr['nowuser'].','.$nowuserid.']';
			return $msg;
		}
		$nowcourseid		= $arr['nowcourseid'];
		$this->nowcoursers	= $this->dbcourse->getone("`id`='$nowcourseid'");//当然进程
		$nowcoursers		= $this->nowcoursers;
		$isend				= 0;
		$this->addlog(array(
			'name'		=> $nowcoursers['name'], //当前进程名称
			'status'	=> $zt,
			'explain'	=> $sm,
			'checkname'	=> $checkname,
			'checkid'	=> $checkid,
			'courseid'	=> $arr['nowcourseid']
		));
		
		$nextcheckid	= '';
		$narr			= $this->getrule(true);
		if($zt == 1){
			$nextcheckid	= $narr['nowuserid']; //下一步审核人
		}
		
		$uparr	= array(
			$this->nstatusfields	=> $zt, 
			$this->statusmanfields	=> $checkname, 
			$ztfields				=> '0'
		);
		if($zt == 2)$uparr[$ztfields] = $zt;
		if($arr['allstep'] == $arr['step'] || $narr['step'] == 0){
			$uparr[$ztfields] 	= $zt;
			$isend			 	= 1;
		}
		$this->mdb->record($uparr, "`id`='$this->id'");
		$msg	= '审核成功';	
			
		$this->flowcheckjudge($nowcoursers, $this->nowcoursers, $zt, $sm);
		
		//前置审核判断
		if(!$this->rock->isempt($nextcheckid)){
			$tempshrid	= (int)$this->dblog->getmou('checkid', "$this->where and `courseid`>0 and `status`=1 and `checkid` in($nextcheckid)");
			if($tempshrid > 0){
				$msg	= $this->check(1, '前置自动审核', $tempshrid);
				return $msg;
			}
		}
		
		if($zt == 2){
			$this->addtodo($this->uid, '您提交['.$this->flowname.']'.$checkname.'审核不通过，原因:['.$sm.']');
			$this->flownothrough($sm);
		}
		
		if($isend == 1){
			$this->endflow($zt);	
		}else{
			if(!$this->rock->isempt($nextcheckid)){
				$this->nexttodocl($nextcheckid);
			}
		}
		return $msg;
	}
	
	private function endflow($zt)
	{
		if($zt==1){
			$this->dbrule->delete($this->where);
			$this->addtodo($this->uid, '您提交的['.$this->flowname.']已全部审核通过');
			$this->flowthrough();
		}
	}
	
	
	/**
		模块重新匹配
	*/
	public function reloadpipei()
	{
		return $this->reloadpipeisss();
	}
	private function reloadpipeisss()
	{
		$whre	= $this->dbwhere->getstring('flowset_'.$this->flownum);
		$where	= "`isturn`=1 and `status`<>1 and `status`<>5 and `uid` in(select `id` from `[Q]admin` where `status`=1) $whre";
		$rows	= $this->mdb->getall($where, '`id`');
		$total	= $this->db->count;
		$str	= '';
		$piep	= 0;
		$wclt	= 0;
		$ycli	= 0;
		$pieid	= '0';
		$wclid	= '0';
		$yclid	= '0';
		$oic	= 0;
		$oistr	= '';
		foreach($rows as $k=>$rs){
			$bid	= $rs['id'];
			$this->initrecord($bid);
			$ztar	= $this->repipeirule();
			$zt		= $ztar[0];
			if($zt == 1){
				$piep++;
				$pieid.=','.$bid.'';
			}
			if($zt == 2){
				$yclid.=','.$bid.'';
				$ycli++;
			}
			if($zt == 3){
				$wclid.=','.$bid.'';
				$wclt++;
			}
			if($ztar[1] != ''){
				$oic++;
				$oistr.=''.$oic.'、【ID:'.$bid.','.$this->urs['name'].'】: '.$ztar[1].'<br>';
			}
		}
		$msg = '['.$this->flowname.']共记录'.$total.'条,重新匹配<font color="blue">('.$piep.')</font>条,异常<font color="red">('.$ycli.')</font>条,完成<font color="#ff6600">('.$wclt.')</font>条。<br>';
		$mess= ''.$msg.'重新匹配ID['.$pieid.'],异常ID['.$yclid.'],完成ID['.$wclid.']<br>'.$oistr.'<br>';
		return array($msg, $mess, $piep, $wclt);
	}
	private function repipeirule()
	{
		$olda	= $this->dbrule->getone($this->where);
		$lea	= 0;
		$leas	= '';
		if(!$olda){
			$tea_ra	= $this->getrule(true);
			$lea	= 1;
			$leas	= '新建流程为【'.$tea_ra['alluser'].':'.$tea_ra['alluserid'].'】;';
			return array($lea, $leas);
		}
		$newa	= $this->getrule(false);
		$bofda	= $this->rock->isempt($newa['nowuserid']);
		if($newa['step'] == 0 || $bofda){
			if($newa['step'] == 0 && $bofda){
				$ztss 	= $newa['nstatus'];
				$uparr	= array($this->statusfields	=> $ztss);
				$this->mdb->record($uparr, "`id`='$this->id'");
				$this->endflow($ztss);
				$lea	= 3;
				$leas	= '标识为'.$ztss.';';
			}else{
				$this->ruleupdate($newa);
				$leas	= '异常,当前没有审核人;';
				$lea	= 2;
			}
		}else{
			$oldcid	= explode('|', $olda['allcourseid']);
			$olduid	= explode('|', $olda['alluserid']);
			$oldcstr= ''; $oldustr='';
			for($i=$olda['step']-1; $i<$olda['allstep']; $i++){
				$oldcstr.='|'.$oldcid[$i].'';
				$oldustr.='|'.$olduid[$i].'';
			}
			$newcid	= explode('|', $newa['allcourseid']);
			$newuid	= explode('|', $newa['alluserid']);
			$newcstr= ''; $newustr='';
			for($i=$newa['step']-1; $i<$newa['allstep']; $i++){
				$newcstr.='|'.$newcid[$i].'';
				$newustr.='|'.$newuid[$i].'';
			}
			if($oldcstr != $newcstr || $oldustr != $newustr){
				$this->ruleupdate($newa);
				$leas	= '【'.$olda['alluser'].'：'.$olda['alluserid'].'】→【'.$newa['alluser'].'：'.$newa['alluserid'].'】;';
				$lea	= 1;
			}
		}
		return array($lea, $leas);
	}
}