PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Tudu/Tudu/Extension/Flow.php

https://github.com/polokk/tudu-web-1
PHP | 1987 lines | 1210 code | 294 blank | 483 comment | 256 complexity | 0c9edfc89510f9445be3eab29d3445e1 MD5 | raw file
  1. <?php
  2. /**
  3. * Tudu Library
  4. *
  5. * LICENSE
  6. *
  7. *
  8. * @category Tudu
  9. * @package Tudu_Model
  10. * @copyright Copyright (c) 2009-2010 Shanghai Best Oray Information S&T CO., Ltd.
  11. * @link http://www.oray.com/
  12. * @version $Id: Flow.php 2755 2013-02-22 09:50:47Z chenyongfa $
  13. */
  14. /**
  15. * 工作流扩展
  16. *
  17. * @category Tudu
  18. * @package Tudu_Tudu_Storage
  19. * @copyright Copyright (c) 2009-2010 Shanghai Best Oray Information S&T CO., Ltd.
  20. */
  21. class Tudu_Tudu_Extension_Flow extends Tudu_Tudu_Extension_Abstract
  22. {
  23. /**
  24. *
  25. * @var string
  26. */
  27. const NODE_HEAD = '^head';
  28. const NODE_END = '^end';
  29. const NODE_BREAK = '^break';
  30. const NODE_UPPER = '^upper';
  31. /**
  32. *
  33. * @var 部门列表
  34. */
  35. protected $_depts;
  36. /**
  37. * 创建步骤
  38. *
  39. * @param $tuduId
  40. * @param $params
  41. */
  42. public function createStep(array $params)
  43. {
  44. return $this->getDao('Dao_Td_Tudu_Step')->createStep($params);
  45. }
  46. /**
  47. * 更新步骤
  48. *
  49. * @param $tuduId
  50. * @param $stepId
  51. * @param $params
  52. */
  53. public function updateStep($tuduId, $stepId, array $params)
  54. {
  55. return $this->getDao('Dao_Td_Tudu_Step')->updateStep($tuduId, $stepId, $params);
  56. }
  57. /**
  58. * 获取步骤数据
  59. *
  60. * @param $tuduId
  61. * @param $stepId
  62. */
  63. public function getStepById($tuduId, $stepId)
  64. {
  65. return $this->getDao('Dao_Td_Tudu_Step')->getStep(array('tuduid' => $tuduId, 'stepid' => $stepId));
  66. }
  67. /**
  68. * 获取步骤列表
  69. *
  70. * @param $tuduId
  71. */
  72. public function getSteps($tuduId)
  73. {
  74. return $this->getDao('Dao_Td_Tudu_Step')->getSteps(array('tuduid' => $tuduId), null, 'ordernum ASC');
  75. }
  76. /**
  77. * 获取工作流
  78. *
  79. * @param $flowId
  80. */
  81. public function getFlowById($flowId)
  82. {
  83. return $this->getDao('Dao_Td_Flow_Flow')->getFlow(array('flowid' => $flowId));
  84. }
  85. /**
  86. *
  87. * @param $orgId
  88. * @param $uniqueId
  89. * @param $users
  90. */
  91. public function prepareRecipients($orgId, $uniqueId, array $users)
  92. {
  93. $addressBook = Tudu_AddressBook::getInstance();
  94. $recipients = array();
  95. foreach ($users as $key => $item) {
  96. $user = $addressBook->searchUser($orgId, $item['email']);
  97. if (null === $user) {
  98. $user = $addressBook->searchContact($uniqueId, $item['email'], $item['truename']);
  99. if (null === $user) {
  100. $user = $addressBook->prepareContact($item['email'], $item['truename']);
  101. }
  102. }
  103. $user['accepterinfo'] = $user['email'] . ' ' . $user['truename'];
  104. $user['percent'] = isset($item['percent']) ? (int) $item['percent'] : 0;
  105. if (isset($item['processindex'])) {
  106. $user['processindex'] = $item['processindex'];
  107. }
  108. if (isset($item['stepstatus'])) {
  109. $user['stepstatus'] = $item['stepstatus'];
  110. }
  111. $recipients[$user['uniqueid']] = $user;
  112. }
  113. return $recipients;
  114. }
  115. /**
  116. * 添加步骤用户
  117. *
  118. * @param $tuduId
  119. * @param $stepId
  120. * @param $users
  121. */
  122. public function addStepUsers($tuduId, $stepId, array $users, $startIndex = null)
  123. {
  124. /* @var $daoStep Dao_Td_Tudu_Step */
  125. $daoStep = $this->getDao('Dao_Td_Tudu_Step');
  126. $isOrder = is_int($startIndex);
  127. $count = 0;
  128. foreach ($users as $item) {
  129. $processIndex = isset($item['processindex'])
  130. ? $item['processindex']
  131. : ($isOrder ? ++$startIndex : 0);
  132. $status = isset($item['stepstatus'])
  133. ? $item['stepstatus']
  134. : ($isOrder && $count == 0 ? 1 : 0);
  135. $params = array(
  136. 'tuduid' => $tuduId,
  137. 'stepid' => $stepId,
  138. 'uniqueid' => $item['uniqueid'],
  139. 'userinfo' => $item['accepterinfo'],
  140. 'status' => $status,
  141. 'processindex' => $processIndex
  142. );
  143. if (array_key_exists('percent', $item)) {
  144. $params['percent'] = (int) $item['percent'];
  145. }
  146. $daoStep->addUser($params);
  147. $count ++;
  148. }
  149. return $count > 0;
  150. }
  151. /**
  152. *
  153. * @param string $tuduId
  154. * @param string $stepId
  155. * @param string $uniqueId
  156. * @param array $params
  157. * @return boolean
  158. */
  159. public function updateStepUser($tuduId, $stepId, $uniqueId, array $params)
  160. {
  161. return $this->getDao('Dao_Td_Tudu_Step')->updateUser($tuduId, $stepId, $uniqueId, $params);
  162. }
  163. /**
  164. *
  165. * @param string $tuduId
  166. */
  167. public function getTuduStepUsers($tuduId)
  168. {
  169. return $this->getDao('Dao_Td_Tudu_Step')->getTuduStepUsers($tuduId);
  170. }
  171. /**
  172. * 获取步骤执行人列表
  173. *
  174. * @param string $tuduId
  175. * @param string $stepId
  176. */
  177. public function getStepUsers($tuduId, $stepId)
  178. {
  179. return $this->getDao('Dao_Td_Tudu_Step')->getUsers($tuduId, $stepId);
  180. }
  181. /**
  182. *
  183. * @param string $tuduId
  184. * @param string $stepId
  185. * @param string $uniqueId
  186. */
  187. public function getStepUser($tuduId, $stepId, $uniqueId)
  188. {
  189. return $this->getDao('Dao_Td_Tudu_Step')->getCurrentStep($tuduId, $stepId, $uniqueId);
  190. }
  191. /**
  192. * 删除步骤执行人
  193. *
  194. * @param $tuduId
  195. * @param $stepId
  196. * @param $uniqueId
  197. */
  198. public function removeStepUsers($tuduId, $stepId, $uniqueId = null)
  199. {
  200. return $this->getDao('Dao_Td_Tudu_Step')->deleteUsers($tuduId, $stepId, $uniqueId);
  201. }
  202. /**
  203. * 更新步骤用户
  204. *
  205. * @param $tuduId
  206. * @param $stepId
  207. * @param $users
  208. */
  209. public function updateStepUsers(Tudu_Tudu_Storage_Tudu &$tudu, $stepId, array $users)
  210. {
  211. $currentUsers = $this->getStepUsers($tudu->tuduId, $stepId);
  212. /* @var $daoTudu Dao_Td_Tudu_Tudu */
  213. $daoTudu = $this->getDao('Dao_Td_Tudu_Tudu');
  214. $processIndex = null;
  215. $removes = array();
  216. foreach ($currentUsers as $item) {
  217. list($email, $trueName) = explode(' ', $item['userinfo'], 2);
  218. if ($item['status'] == 2 && !array_key_exists($email, $users)) {
  219. $processIndex = (int) $item['processindex'];
  220. } else {
  221. if (null === $processIndex) {
  222. $processIndex = (int) $item['processindex'] - 1;
  223. }
  224. $removes[] = $item['uniqueid'];
  225. }
  226. // 正在审批的移除待审批标签
  227. if ($item['status'] == 1) {
  228. $daoTudu->deleteLabel($tudu->tuduId, $item['uniqueid'], '^e');
  229. if (!array_key_exists($email, $tudu->to)
  230. && !array_key_exists($email, $tudu->cc)
  231. && $email != $tudu->sender)
  232. {
  233. $daoTudu->deleteLabel($tudu->tuduId, $item['uniqueid'], '^i');
  234. }
  235. }
  236. }
  237. foreach ($users as $k => $item) {
  238. $users[$k]['processindex'] = $users[$k]['processindex'] + $processIndex;
  239. }
  240. if ($removes) {
  241. $this->removeStepUsers($tudu->tuduId, $stepId, $removes);
  242. }
  243. // 添加审批人
  244. $recipients = $this->prepareRecipients($tudu->orgId, $stepId, $users);
  245. $this->addStepUsers($tudu->tuduId, $stepId, $recipients, $processIndex);
  246. }
  247. /**
  248. * 删除步骤
  249. *
  250. * @param $tuduId
  251. * @param $stepId
  252. */
  253. public function deleteStep($tuduId, $stepId)
  254. {
  255. return $this->getDao('Dao_Td_Tudu_Step')->deleteStep($tuduId, $stepId);
  256. }
  257. /**
  258. * 删除后续步骤
  259. *
  260. * @param string $tuduId
  261. * @param string $stepId
  262. */
  263. public function deleteNextSteps($tuduId, $stepId)
  264. {
  265. return $this->getDao('Dao_Td_Tudu_Step')->removeNextSteps($tuduId, $stepId);
  266. }
  267. /**
  268. * 删除所有步骤
  269. *
  270. * @param $tuduId
  271. * @param $stepId
  272. */
  273. public function deleteAllSteps($tuduId)
  274. {
  275. return $this->getDao('Dao_Td_Tudu_Step')->deleteSteps($tuduId);
  276. }
  277. /**
  278. * 设置图度当前步骤
  279. *
  280. * @param $tuduId
  281. * @param $stepId
  282. */
  283. public function flowToStep($tuduId, $stepId)
  284. {
  285. //return $this->getDao('Dao_Td_Tudu_Tudu')->updateTudu($tuduId, array('stepid' => $stepId));
  286. }
  287. /**
  288. *
  289. * @param $tudu
  290. * @param $stepId
  291. * @param $users
  292. */
  293. public function cancelStep(Tudu_Tudu_Storage_Tudu &$tudu, $stepId)
  294. {
  295. $this->updateStep($tudu->tuduId, $stepId, array('status' => 4));
  296. $users = $this->getStepUsers($tudu->tuduId, $stepId);
  297. /* @var $daoTudu Dao_Td_Tudu_Tudu */
  298. $daoTudu = $this->getDao('Dao_Td_Tudu_Tudu');
  299. foreach ($users as $item) {
  300. list($email, $trueName) = explode(' ', $item['userinfo'], 2);
  301. // 正在审批的移除待审批标签
  302. if ($item['status'] == 1) {
  303. $daoTudu->deleteLabel($tudu->tuduId, $item['uniqueid'], '^e');
  304. if (!array_key_exists($email, $tudu->to)
  305. && !array_key_exists($email, $tudu->cc)
  306. && $email != $tudu->sender)
  307. {
  308. $daoTudu->deleteLabel($tudu->tuduId, $item['uniqueid'], '^i');
  309. }
  310. }
  311. }
  312. }
  313. /**
  314. *
  315. * @param Tudu_Tudu_Storage_Tudu $tudu
  316. * @param array $params
  317. * @return array
  318. */
  319. public function onPrepare(Tudu_Tudu_Storage_Tudu &$tudu, array $params)
  320. {
  321. if ($tudu->flowId && !$tudu->stepId) {
  322. $this->onPrepareFlow($tudu);
  323. }
  324. if ($tudu->reviewer && !$tudu->to && $tudu->type != 'notice') {
  325. $tudu->to = Tudu_Tudu_Storage::formatRecipients($tudu->from);
  326. }
  327. }
  328. /**
  329. * 整理工作步骤
  330. *
  331. * @param Tudu_Tudu_Storage_Tudu $tudu
  332. */
  333. public function onPrepareFlow(Tudu_Tudu_Storage_Tudu &$tudu)
  334. {
  335. $flow = $this->getFlowById($tudu->flowId);
  336. if (null !== $flow) {
  337. $flow = $flow->toArray();
  338. // 没有步骤
  339. if (count($flow['steps']) <= 0) {
  340. require_once 'Tudu/Tudu/Exception.php';
  341. throw new Tudu_Tudu_Exception('Flow has not any steps', Tudu_Tudu_Exception::CODE_FLOW_STEP_NULL);
  342. }
  343. // 整理抄送人
  344. if (!empty($flow['cc'])) {
  345. $cc = array();
  346. foreach ($flow['cc'] as $key => $item) {
  347. if (false !== strpos($key, '@')) {
  348. $cc[$key] = array('email' => $key, 'truename' => $item[0]);
  349. } else {
  350. $cc[$key] = array('groupid' => $key, 'truename' => $item[0]);
  351. }
  352. }
  353. $tudu->cc = array_merge($tudu->cc, $cc);
  354. }
  355. // 第一步骤ID
  356. $steps = $flow['steps'];
  357. $prevUsers = array(array('email' => $tudu->email));
  358. $prevType = 0;
  359. $addressBook = Tudu_AddressBook::getInstance();
  360. $depts = $this->_getDepartments($tudu->orgId);
  361. $tuduSteps = array();
  362. $orderNum = 1;
  363. foreach ($steps as $key => $step) {
  364. $stepId = $step['id'];
  365. if ($step['type'] == 1) {
  366. // 上级审批
  367. if ($step['users'] == '^upper') {
  368. // 上一步是审批
  369. $reviewerIds = array();
  370. if ($prevType == 1) {
  371. foreach ($prevUsers as $item) {
  372. foreach ($item as $user) {
  373. $user = $addressBook->searchUser($tudu->orgId, $user['email']);
  374. if (!$user) {
  375. require_once 'Tudu/Tudu/Exception.php';
  376. throw new Tudu_Tudu_Exception('User is not exists', Tudu_Tudu_Exception::CODE_NOT_EXISTS_USER);
  377. }
  378. $moderatorIds = $this->_getUpper($user['email'], $tudu->orgId, $user['deptid']);
  379. foreach ($moderatorIds as $uid) {
  380. $reviewerIds[] = $uid;
  381. }
  382. }
  383. }
  384. } else {
  385. foreach ($prevUsers as $user) {
  386. $user = $addressBook->searchUser($tudu->orgId, $user['email']);
  387. if (!$user) {
  388. require_once 'Tudu/Tudu/Exception.php';
  389. throw new Tudu_Tudu_Exception('User is not exists', Tudu_Tudu_Exception::CODE_NOT_EXISTS_USER);
  390. }
  391. $moderatorIds = $this->_getUpper($user['email'], $tudu->orgId, $user['deptid']);
  392. foreach ($moderatorIds as $uid) {
  393. $reviewerIds[] = $uid;
  394. }
  395. }
  396. }
  397. if (empty($reviewerIds)) {
  398. require_once 'Tudu/Tudu/Exception.php';
  399. throw new Tudu_Tudu_Exception('Upper is not exists', Tudu_Tudu_Exception::CODE_NOT_EXISTS_UPPER);
  400. }
  401. $reviewers = array();
  402. $reviewerIds = array_unique($reviewerIds);
  403. foreach ($reviewerIds as $uId) {
  404. $user = $addressBook->searchUser($tudu->orgId, $uId . '@' . $tudu->orgId);
  405. if (empty($user)) {
  406. require_once 'Tudu/Tudu/Exception.php';
  407. throw new Tudu_Tudu_Exception('User is not exists', Tudu_Tudu_Exception::CODE_NOT_EXISTS_USER);
  408. }
  409. $reviewers[] = $user;
  410. }
  411. $users = array($reviewers);
  412. $prevUsers = $users;
  413. // 指定
  414. } else {
  415. $prevUsers = $users = Tudu_Tudu_Storage::formatReviewer($step['users']);
  416. foreach ($users as $item) {
  417. foreach ($item as $u) {
  418. $user = $addressBook->searchUser($tudu->orgId, $u['email']);
  419. if (!$user) {
  420. require_once 'Tudu/Tudu/Exception.php';
  421. throw new Tudu_Tudu_Exception('User is not exists', Tudu_Tudu_Exception::CODE_NOT_EXISTS_USER);
  422. }
  423. }
  424. }
  425. }
  426. $recipients = array();
  427. $processIndex = 1;
  428. foreach ($users as $item) {
  429. foreach ($item as $user) {
  430. $recipients[] = array(
  431. 'email' => $user['email'],
  432. 'truename' => $user['truename'],
  433. 'processindex' => $processIndex,
  434. 'stepstatus' => $processIndex == 1 ? 1 : 0
  435. );
  436. }
  437. $processIndex ++;
  438. }
  439. $tuduSteps[$stepId] = array(
  440. 'orgid' => $tudu->orgId,
  441. 'tuduid' => $tudu->tuduId,
  442. 'uniqueid' => $tudu->uniqueId,
  443. 'stepid' => $stepId,
  444. 'type' => Dao_Td_Tudu_Step::TYPE_EXAMINE,
  445. 'prevstepid' => $step['prev'],
  446. 'nextstepid' => $step['next'],
  447. 'users' => $recipients,
  448. 'ordernum' => $orderNum ++,
  449. 'createtime' => time()
  450. );
  451. } else {
  452. $prevUsers = $users = Tudu_Tudu_Storage::formatRecipients($step['users']);
  453. foreach ($prevUsers as $u) {
  454. $user = $addressBook->searchUser($tudu->orgId, $u['email']);
  455. if (!$user) {
  456. require_once 'Tudu/Tudu/Exception.php';
  457. throw new Tudu_Tudu_Exception('User is not exists', Tudu_Tudu_Exception::CODE_NOT_EXISTS_USER);
  458. }
  459. }
  460. $tuduSteps[$stepId] = array(
  461. 'orgid' => $tudu->orgId,
  462. 'tuduid' => $tudu->tuduId,
  463. 'uniqueid' => $tudu->uniqueId,
  464. 'stepid' => $stepId,
  465. 'type' => $step['type'] == 2 ? Dao_Td_Tudu_Step::TYPE_CLAIM : Dao_Td_Tudu_Step::TYPE_EXECUTE,
  466. 'prevstepid' => $step['prev'],
  467. 'nextstepid' => $step['next'],
  468. 'users' => $users,
  469. 'ordernum' => $orderNum ++,
  470. 'createtime' => time()
  471. );
  472. }
  473. $prevType = $step['type'];
  474. }
  475. $tudu->steps = $tuduSteps;
  476. // 第一步骤ID
  477. $firstStep = reset($tuduSteps);
  478. $tudu->stepId = $firstStep['stepid'];
  479. if ($firstStep['type'] == 1) {
  480. $users = $firstStep['users'];
  481. $reviewers = array();
  482. foreach ($users as $user) {
  483. if ($user['processindex'] == 1) {
  484. $reviewers[] = $user;
  485. }
  486. }
  487. $tudu->reviewer = array($reviewers);
  488. } else {
  489. $tudu->to = $firstStep['users'];
  490. }
  491. $tudu->status = Dao_Td_Tudu_Tudu::STATUS_DOING;
  492. }
  493. }
  494. /**
  495. * 根据工作流创建图度步骤
  496. *
  497. * @param $tudu
  498. */
  499. public function createFlowSteps(Tudu_Tudu_Storage_Tudu &$tudu)
  500. {
  501. if ($tudu->flowId && $tudu->steps) {
  502. $steps = $tudu->steps;
  503. // 第一步骤ID
  504. /*$firstStep = reset($steps);
  505. $tudu->stepId = $firstStep['stepid'];
  506. if ($firstStep['type'] == 1) {
  507. $users = $firstStep['users'];
  508. $reviewers = array();
  509. foreach ($users as $user) {
  510. if ($user['processindex'] == 1) {
  511. $reviewers[] = $user;
  512. }
  513. }
  514. $tudu->reviewer = array($reviewers);
  515. } else {
  516. $tudu->to = $firstStep['users'];
  517. }*/
  518. } else {
  519. $steps = array();
  520. $currentStepId = null;
  521. $orderNum = 1;
  522. if ($tudu->reviewer) {
  523. $reviewers = $tudu->reviewer;
  524. $users = array();
  525. $processIndex = 1;
  526. foreach ($reviewers as $item) {
  527. foreach ($item as $reviewer) {
  528. $users[] = array(
  529. 'email' => $reviewer['email'],
  530. 'truename' => $reviewer['truename'],
  531. 'processindex' => $processIndex,
  532. 'stepstatus' => $processIndex == 1 ? 1 : 0
  533. );
  534. }
  535. $processIndex ++;
  536. }
  537. $stepId = Dao_Td_Tudu_Step::getStepId();
  538. $steps[$stepId] = array(
  539. 'orgid' => $tudu->orgId,
  540. 'tuduid' => $tudu->tuduId,
  541. 'uniqueid' => $tudu->uniqueId,
  542. 'stepid' => $stepId,
  543. 'type' => Dao_Td_Tudu_Step::TYPE_EXAMINE,
  544. 'prevstepid' => self::NODE_HEAD,
  545. 'nextstepid' => self::NODE_END,
  546. 'users' => $users,
  547. 'ordernum' => $orderNum ++,
  548. 'createtime' => time()
  549. );
  550. $currentStepId = $stepId;
  551. }
  552. if ($tudu->to) {
  553. $stepId = Dao_Td_Tudu_Step::getStepId();
  554. $prevId = self::NODE_HEAD;
  555. if ($currentStepId) {
  556. $steps[$currentStepId]['nextstepid'] = $stepId;
  557. $prevId = $currentStepId;
  558. } else {
  559. $currentStepId = $stepId;
  560. }
  561. $steps[$stepId] = array(
  562. 'orgid' => $tudu->orgId,
  563. 'tuduid' => $tudu->tuduId,
  564. 'uniqueid' => $tudu->uniqueId,
  565. 'stepid' => $stepId,
  566. 'type' => $tudu->acceptMode ? Dao_Td_Tudu_Step::TYPE_CLAIM : Dao_Td_Tudu_Step::TYPE_EXECUTE,
  567. 'prevstepid' => $prevId,
  568. 'nextstepid' => self::NODE_END,
  569. 'users' => $tudu->to,
  570. 'ordernum' => $orderNum ++,
  571. 'createtime' => time()
  572. );
  573. }
  574. }
  575. /*
  576. foreach ($tudu->steps as $key => $step) {
  577. $stepId = $step['id'];
  578. if ($step['type'] == 1) {
  579. $users = array();
  580. $processIndex = 1;
  581. $reviewers = array();
  582. if ($step['users'] == self::NODE_UPPER) {
  583. // 取上一步骤
  584. $prevStep = $tudu->steps[$key - 1];
  585. if (isset($prevStep)) {
  586. $addressBook = Tudu_AddressBook::getInstance();
  587. $reviewerIds = array();
  588. if ($prevStep['type'] == 1) {
  589. $prevUsers = Tudu_Tudu_Storage::formatReviewer($prevStep['users']);
  590. foreach ($prevUsers as $item) {
  591. foreach ($item as $user) {
  592. $user = $addressBook->searchUser($tudu->orgId, $user['email']);
  593. if ($user) {
  594. $dept = $this->getDepartment($tudu->orgId, $user['deptid']);
  595. if (empty($dept->moderators)) {
  596. continue;
  597. }
  598. foreach ($dept->moderators as $m) {
  599. $reviewerIds[] = $m;
  600. }
  601. }
  602. }
  603. }
  604. } else {
  605. $prevUsers = Tudu_Tudu_Storage::formatRecipients($prevStep['users']);
  606. foreach ($prevUsers as $user) {
  607. $user = $addressBook->searchUser($tudu->orgId, $user['email']);
  608. if ($user) {
  609. $dept = $this->getDepartment($tudu->orgId, $user['deptid']);
  610. if (empty($dept->moderators)) {
  611. continue;
  612. }
  613. foreach ($dept->moderators as $m) {
  614. $reviewerIds[] = $m;
  615. }
  616. }
  617. }
  618. }
  619. if (empty($reviewerIds)) {
  620. //throw new Zend_Controller_Action_Exception('', 404);
  621. }
  622. $reviewerIds = array_unique($reviewerIds);
  623. foreach ($reviewerIds as $userId) {
  624. $user = $addressBook->searchUser($tudu->orgId, $userId . '@' . $tudu->orgId);
  625. if ($user) {
  626. end($reviewers);
  627. $last = key($reviewers);
  628. $reviewers[$last][] = array('email' => $user['email'], 'truename' => $user['truename']);
  629. }
  630. }
  631. }
  632. } else {
  633. $reviewers = Tudu_Tudu_Storage:: _formatReviewer($step['users']);
  634. }
  635. foreach ($reviewers as $item) {
  636. foreach ($item as $reviewer) {
  637. $users[] = array(
  638. 'email' => $reviewer['email'],
  639. 'truename' => $reviewer['truename'],
  640. 'processindex' => $processIndex,
  641. 'stepstatus' => $processIndex == 1 ? 1 : 0
  642. );
  643. }
  644. $processIndex ++;
  645. }
  646. $steps[$stepId] = array(
  647. 'orgid' => $tudu->orgId,
  648. 'tuduid' => $tudu->tuduId,
  649. 'uniqueid' => $tudu->uniqueId,
  650. 'stepid' => $stepId,
  651. 'type' => Dao_Td_Tudu_Step::TYPE_EXAMINE,
  652. 'prevstepid' => $step['prev'],
  653. 'nextstepid' => $step['next'],
  654. 'users' => $users,
  655. 'ordernum' => $orderNum ++
  656. );
  657. } else {
  658. $recipients = Tudu_Tudu_Storage::formatRecipients($step['users']);
  659. $steps[$stepId] = array(
  660. 'orgid' => $tudu->orgId,
  661. 'tuduid' => $tudu->tuduId,
  662. 'uniqueid' => $tudu->uniqueId,
  663. 'stepid' => $stepId,
  664. 'type' => $step['type'] == 2 ? Dao_Td_Tudu_Step::TYPE_CLAIM : Dao_Td_Tudu_Step::TYPE_EXECUTE,
  665. 'prevstepid' => $step['prev'],
  666. 'nextstepid' => $step['next'],
  667. 'users' => $recipients,
  668. 'ordernum' => $orderNum ++
  669. );
  670. }
  671. }
  672. */
  673. foreach ($steps as $step) {
  674. if ($this->createStep($step)) {
  675. $recipients = $this->prepareRecipients($tudu->orgId, $tudu->uniqueId, $step['users']);
  676. $processIndex = $step['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE ? 0 : null;
  677. $this->addStepUsers($tudu->tuduId, $step['stepid'], $recipients, $processIndex);
  678. }
  679. }
  680. $tudu->stepNum = count($steps);
  681. return true;
  682. }
  683. /**
  684. * 更新图度工作流后续步骤
  685. *
  686. * @param $tudu
  687. */
  688. public function updateFlowSteps(Tudu_Tudu_Storage_Tudu &$tudu)
  689. {
  690. /*if ($tudu->stepId != self::NODE_HEAD && $tudu->stepId != self::NODE_BREAK && !$tudu->isDraft()) {
  691. return false;
  692. }*/
  693. $steps = $this->getSteps($tudu->tuduId)->toArray('stepid');
  694. $currentStep = $tudu->stepId && false === strpos($tudu->stepId, '^') ? $steps[$tudu->stepId] : array_pop($steps);
  695. $stepNum = count($steps);
  696. $newSteps = array();
  697. // 当前为审批步骤
  698. if ($currentStep['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE) {
  699. $stepId = $currentStep['stepid'];
  700. $reviewer = array();
  701. $pidx = null;
  702. // 获取步骤审批人
  703. $users = $this->getStepUsers($tudu->tuduId, $stepId);//var_dump($users);exit;
  704. foreach ($users as &$user) {
  705. if ($user['status'] == 2) {
  706. continue;
  707. }
  708. $userInfo = explode(' ', $user['userinfo']);
  709. if ($pidx == $user['processindex']) {
  710. end($reviewer);
  711. $last = key($reviewer);
  712. $reviewer[$last][] = array('email' => $userInfo[0], 'truename' => $userInfo[1]);
  713. } else {
  714. $reviewer[] = array(array('email' => $userInfo[0], 'truename' => $userInfo[1]));
  715. }
  716. $pidx = $user['processindex'];
  717. }
  718. $tudu->reviewer = $reviewer;
  719. $tudu->stepId = $stepId;
  720. var_dump($tudu->reviewer);
  721. // 其他
  722. } else {
  723. }
  724. exit;
  725. }
  726. /**
  727. * 创建图度步骤
  728. *
  729. * @param Tudu_Tudu_Storage_Tudu $tudu
  730. */
  731. public function createTuduSteps(Tudu_Tudu_Storage_Tudu &$tudu)
  732. {
  733. $steps = array();
  734. $currentStepId = null;
  735. $orderNum = 1;
  736. if ($tudu->reviewer) {
  737. $reviewers = $tudu->reviewer;
  738. $users = array();
  739. $processIndex = 1;
  740. foreach ($reviewers as $item) {
  741. foreach ($item as $reviewer) {
  742. $users[] = array(
  743. 'email' => $reviewer['email'],
  744. 'truename' => $reviewer['truename'],
  745. 'processindex' => $processIndex,
  746. 'stepstatus' => $processIndex == 1 ? 1 : 0
  747. );
  748. }
  749. $processIndex ++;
  750. }
  751. $stepId = Dao_Td_Tudu_Step::getStepId();
  752. $steps[$stepId] = array(
  753. 'orgid' => $tudu->orgId,
  754. 'tuduid' => $tudu->tuduId,
  755. 'uniqueid' => $tudu->uniqueId,
  756. 'stepid' => $stepId,
  757. 'type' => Dao_Td_Tudu_Step::TYPE_EXAMINE,
  758. 'prevstepid' => self::NODE_HEAD,
  759. 'nextstepid' => self::NODE_END,
  760. 'users' => $users,
  761. 'ordernum' => $orderNum ++,
  762. 'createtime' => time()
  763. );
  764. $currentStepId = $stepId;
  765. }
  766. if ($tudu->to) {
  767. $stepId = Dao_Td_Tudu_Step::getStepId();
  768. $prevId = self::NODE_HEAD;
  769. if ($currentStepId) {
  770. $steps[$currentStepId]['nextstepid'] = $stepId;
  771. $prevId = $currentStepId;
  772. } else {
  773. $currentStepId = $stepId;
  774. }
  775. if ($tudu->stepto) {
  776. $countTo = count($tudu->stepto);
  777. $i = 0;
  778. foreach ($tudu->stepto as $item) {
  779. $i++;
  780. $users = array();
  781. foreach ($item as $to) {
  782. $users[] = array(
  783. 'email' => $to['email'],
  784. 'truename' => $to['truename']
  785. );
  786. }
  787. $nextStepId = Dao_Td_Tudu_Step::getStepId();
  788. $steps[$stepId] = array(
  789. 'orgid' => $tudu->orgId,
  790. 'tuduid' => $tudu->tuduId,
  791. 'uniqueid' => $tudu->uniqueId,
  792. 'stepid' => $stepId,
  793. 'type' => $tudu->acceptMode ? Dao_Td_Tudu_Step::TYPE_CLAIM : Dao_Td_Tudu_Step::TYPE_EXECUTE,
  794. 'prevstepid' => $prevId,
  795. 'nextstepid' => $countTo == $i ? self::NODE_END : $nextStepId,
  796. 'users' => $users,
  797. 'ordernum' => $orderNum ++,
  798. 'createtime' => time()
  799. );
  800. $prevId = $stepId;
  801. $stepId = $nextStepId;
  802. }
  803. }
  804. }
  805. foreach ($steps as $step) {
  806. if ($this->createStep($step)) {
  807. $recipients = $this->prepareRecipients($tudu->orgId, $tudu->uniqueId, $step['users']);
  808. $processIndex = $step['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE ? 0 : null;
  809. $this->addStepUsers($tudu->tuduId, $step['stepid'], $recipients, $processIndex);
  810. }
  811. }
  812. $tudu->stepId = $currentStepId;
  813. $tudu->stepNum = count($steps);
  814. return true;
  815. }
  816. /**
  817. * 更新图度后续步骤
  818. *
  819. * @param $tudu
  820. */
  821. public function updateTuduSteps(Tudu_Tudu_Storage_Tudu &$tudu, $cancelCurrent = true)
  822. {
  823. // 草稿
  824. if ($tudu->isDraft() || $tudu->stepId == self::NODE_HEAD || $tudu->stepId == self::NODE_BREAK) {
  825. $this->deleteAllSteps($tudu->tuduId);
  826. if ($tudu->flowId) {
  827. $this->onPrepareFlow($tudu);
  828. if ($tudu->isChange('to')) {
  829. $manager = Tudu_Tudu_Manager::getInstance();
  830. $to = $tudu->getAttribute('to');
  831. $to = isset($to) ? Tudu_Tudu_Storage::formatReceiver($to) : null;
  832. $manager->updateTudu($tudu->tuduId, array('to' => $to));
  833. }
  834. return $this->createFlowSteps($tudu);
  835. } else {
  836. return $this->createTuduSteps($tudu);
  837. }
  838. }
  839. if ($tudu->flowId) {
  840. return true;
  841. //return $this->updateFlowSteps($tudu);
  842. }
  843. $steps = $this->getSteps($tudu->tuduId)->toArray('stepid');
  844. if ($tudu->stepId && false === strpos($tudu->stepId, '^')) {
  845. $currentStep = $steps[$tudu->stepId];
  846. } else {
  847. foreach ($steps as $step) {
  848. if ($step['stepstatus'] != 4) {
  849. $currentStep = $step;
  850. break;
  851. }
  852. }
  853. }
  854. //$currentStep = $tudu->stepId && false === strpos($tudu->stepId, '^') ? $steps[$tudu->stepId] : array_pop($steps);
  855. // 当前为审批步骤
  856. $stepNum = count($steps);
  857. $newSteps = array();
  858. $updatePrevStepId = null;
  859. if (isset($currentStep) && $currentStep['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE) {
  860. $nextStepId = $currentStep['stepid'];
  861. $execStepId = Dao_Td_Tudu_Step::getStepId();
  862. if ($tudu->reviewer) {
  863. $reviewers = $tudu->reviewer;
  864. $users = array();
  865. $processIndex = 1;
  866. foreach ($reviewers as $item) {
  867. foreach ($item as $reviewer) {
  868. $users[] = array(
  869. 'email' => $reviewer['email'],
  870. 'truename' => $reviewer['truename'],
  871. 'processindex' => $processIndex,
  872. 'stepstatus' => $processIndex == 1 ? 1 : 0
  873. );
  874. }
  875. $processIndex ++;
  876. }
  877. // 更新审批步骤审批人
  878. $this->updateStepUsers($tudu, $currentStep['stepid'], $users);
  879. $updatePrevStepId = $prevStepId = $currentStep['stepid'];
  880. $tudu->stepId = $currentStep['stepid'];
  881. } else {
  882. // 审批步骤作废
  883. //$this->cancelStep($tudu, $currentStep['stepid']);
  884. $this->updateStepUsers($tudu, $currentStep['stepid'], array());
  885. $updatePrevStepId = $prevStepId = $currentStep['prevstepid'];
  886. $tudu->stepId = $execStepId;
  887. }
  888. if ($tudu->type != 'notice') {
  889. $updateNextStepId = $stepId = $execStepId;
  890. if ($tudu->stepto) {
  891. $countTo = count($tudu->stepto);
  892. $i = 0;
  893. $orderNum = $currentStep['ordernum'];
  894. foreach ($tudu->stepto as $item) {
  895. $i++;
  896. $users = array();
  897. foreach ($item as $to) {
  898. $users[] = array(
  899. 'email' => $to['email'],
  900. 'truename' => $to['truename']
  901. );
  902. }
  903. $nextStepId = Dao_Td_Tudu_Step::getStepId();
  904. $newSteps[] = array(
  905. 'orgid' => $tudu->orgId,
  906. 'tuduid' => $tudu->tuduId,
  907. 'uniqueid' => $tudu->uniqueId,
  908. 'stepid' => $stepId,
  909. 'type' => $tudu->acceptMode ? Dao_Td_Tudu_Step::TYPE_CLAIM : Dao_Td_Tudu_Step::TYPE_EXECUTE,
  910. 'prevstepid' => $prevStepId,
  911. 'nextstepid' => $countTo == $i ? self::NODE_END : $nextStepId,
  912. 'users' => $users,
  913. 'ordernum' => ++$orderNum,
  914. 'createtime' => time()
  915. );
  916. $prevStepId = $stepId;
  917. $stepId = $nextStepId;
  918. }
  919. }
  920. $nextStepId = $stepId;
  921. } else {
  922. $updateNextStepId = $nextStepId = self::NODE_END;
  923. }
  924. // 其他
  925. } else {
  926. $isChangeTo = false;
  927. // 比较图度执行人
  928. $stepUsers = $this->getTuduStepUsers($tudu->tuduId);
  929. $stepTo = array(); //修改前的步骤执行人
  930. $stepSize = 0; //修改前的步骤个数
  931. $tempStepId = null;
  932. foreach ($stepUsers as &$u) {
  933. if ($tudu->stepId == $u['stepid'] && $u['type'] == Dao_Td_Tudu_Step::TYPE_EXECUTE && $u['stepstatus'] != 4) {
  934. if ($tempStepId != $u['stepid']) {
  935. $stepSize++;
  936. }
  937. $tempStepId = $u['stepid'];
  938. $info = explode(' ', $u['userinfo']);
  939. $u['email'] = $info[0];
  940. $u['truename'] = $info[1];
  941. $stepTo[$u['email']] = $u;
  942. }
  943. }
  944. $currentTo = array(); //当前修改后的执行人
  945. $currentStepSize = 0; //当前修改后步骤个数
  946. foreach ($tudu->stepto as $item) {
  947. foreach ($item as $to) {
  948. $currentTo[$to['email']] = $to;
  949. }
  950. $currentStepSize++;
  951. }
  952. $src = array_keys($stepTo);
  953. $cur = array_keys($currentTo);
  954. $srcCount = count($src);
  955. $isChangeTo = $stepSize != $currentStepSize || count($cur) != $srcCount || count(array_uintersect($src, $cur, "strcasecmp")) != $srcCount;
  956. // 步骤作废
  957. if ($isChangeTo || $tudu->isChange('acceptmode')) {
  958. if ($cancelCurrent) {
  959. $this->updateStep($tudu->tuduId, $currentStep['stepid'], array('status' => 4));
  960. $updatePrevStepId = $prevStepId = $currentStep['prevstepid'];
  961. } else {
  962. $updatePrevStepId = $prevStepId = $currentStep['stepid'];
  963. }
  964. } else {
  965. $updatePrevStepId = $prevStepId = $currentStep['stepid'];
  966. $tudu->stepId = $prevStepId;
  967. }
  968. $updateNextStepId = $nextStepId = null;
  969. $prevId = $prevStepId;
  970. $orderNum = $currentStep['ordernum'];
  971. if ($tudu->reviewer) {
  972. // 前一步骤作废
  973. if ($cancelCurrent) {
  974. $this->updateStep($tudu->tuduId, $prevId, array('status' => 4));
  975. }
  976. $reviewers = $tudu->reviewer;
  977. $users = array();
  978. $processIndex = 1;
  979. foreach ($reviewers as $item) {
  980. foreach ($item as $reviewer) {
  981. $users[] = array(
  982. 'email' => $reviewer['email'],
  983. 'truename' => $reviewer['truename'],
  984. 'processindex' => $processIndex
  985. );
  986. }
  987. $processIndex ++;
  988. }
  989. $stepId = Dao_Td_Tudu_Step::getStepId();
  990. /*插入修改人
  991. $nextStepId = Dao_Td_Tudu_Step::getStepId();
  992. $newSteps[$stepId] = array(
  993. 'orgid' => $tudu->orgId,
  994. 'tuduid' => $tudu->tuduId,
  995. 'stepid' => $stepId,
  996. 'uniqueid' => $tudu->uniqueId,
  997. 'prevstepid' => $prevId,
  998. 'nextstepid' => $nextStepId,
  999. 'type' => Dao_Td_Tudu_Step::TYPE_EXECUTE,
  1000. 'ordernum' => ++$orderNum,
  1001. 'createtime' => time(),
  1002. 'users' => array(0 => array('email' => $tudu->email, 'truename' => $tudu->poster))
  1003. );
  1004. $prevId = $stepId;
  1005. $stepId = $nextStepId;
  1006. */
  1007. $newSteps[$stepId] = array(
  1008. 'orgid' => $tudu->orgId,
  1009. 'tuduid' => $tudu->tuduId,
  1010. 'stepid' => $stepId,
  1011. 'uniqueid' => $tudu->uniqueId,
  1012. 'prevstepid' => $prevId,
  1013. 'nextstepid' => '^end',
  1014. 'type' => Dao_Td_Tudu_Step::TYPE_EXAMINE,
  1015. 'ordernum' => ++$orderNum,
  1016. 'createtime' => time(),
  1017. 'users' => $users
  1018. );
  1019. $prevId = $stepId;
  1020. if (!$nextStepId) {
  1021. $updateNextStepId = $nextStepId = $stepId;
  1022. }
  1023. }
  1024. if ($isChangeTo || count($newSteps) || $tudu->isChange('acceptmode')) {
  1025. $stepId = Dao_Td_Tudu_Step::getStepId();
  1026. if (!$nextStepId) {
  1027. $updateNextStepId = $nextStepId = $stepId;
  1028. }
  1029. if (isset($newSteps[$prevId])) {
  1030. $newSteps[$prevId]['nextstepid'] = $stepId;
  1031. }
  1032. // 转发
  1033. if ($tudu->action == 'forward') {
  1034. $newSteps[$stepId] = array(
  1035. 'orgid' => $tudu->orgId,
  1036. 'tuduid' => $tudu->tuduId,
  1037. 'stepid' => $stepId,
  1038. 'uniqueid' => $tudu->uniqueId,
  1039. 'prevstepid' => $prevId,
  1040. 'nextstepid' => '^end',
  1041. 'type' => $tudu->acceptMode ? Dao_Td_Tudu_Step::TYPE_CLAIM : Dao_Td_Tudu_Step::TYPE_EXECUTE,
  1042. 'ordernum' => ++$orderNum,
  1043. 'createtime' => time(),
  1044. 'users' => $tudu->to
  1045. );
  1046. } else {
  1047. // 修改
  1048. if ($tudu->stepto) {
  1049. $countTo = count($tudu->stepto);
  1050. $i = 0;
  1051. foreach ($tudu->stepto as $item) {
  1052. $i++;
  1053. $users = array();
  1054. foreach ($item as $to) {
  1055. $users[] = array(
  1056. 'email' => $to['email'],
  1057. 'truename' => $to['truename']
  1058. );
  1059. }
  1060. $nextId = Dao_Td_Tudu_Step::getStepId();
  1061. $newSteps[$stepId] = array(
  1062. 'orgid' => $tudu->orgId,
  1063. 'tuduid' => $tudu->tuduId,
  1064. 'uniqueid' => $tudu->uniqueId,
  1065. 'stepid' => $stepId,
  1066. 'type' => $tudu->acceptMode ? Dao_Td_Tudu_Step::TYPE_CLAIM : Dao_Td_Tudu_Step::TYPE_EXECUTE,
  1067. 'prevstepid' => $prevId,
  1068. 'nextstepid' => $countTo == $i ? self::NODE_END : $nextId,
  1069. 'users' => $users,
  1070. 'ordernum' => ++$orderNum,
  1071. 'createtime' => time()
  1072. );
  1073. $prevId = $stepId;
  1074. $stepId = $nextId;
  1075. }
  1076. }
  1077. }
  1078. }
  1079. if ($nextStepId) {
  1080. $tudu->stepId = $updateNextStepId;
  1081. }
  1082. }
  1083. if (!empty($newSteps)) {
  1084. // 移除后随未开始执行的步骤
  1085. foreach ($steps as $step) {
  1086. if ($step['ordernum'] > $currentStep['ordernum']) {
  1087. $this->deleteStep($tudu->tuduId, $step['stepid']);
  1088. $stepNum--;
  1089. }
  1090. }
  1091. foreach ($newSteps as $step) {
  1092. if ($this->createStep($step)) {
  1093. $recipients = $this->prepareRecipients($tudu->orgId, $tudu->uniqueId, $step['users']);
  1094. $processIndex = $step['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE ? 0 : null;
  1095. $this->addStepUsers($tudu->tuduId, $step['stepid'], $recipients, $processIndex);
  1096. $stepNum++;
  1097. }
  1098. }
  1099. $this->updateStep($tudu->tuduId, $updatePrevStepId, array('nextstepid' => $updateNextStepId));
  1100. }
  1101. $tudu->stepNum = $stepNum;
  1102. /*return $this->getDao('Dao_Td_Tudu_Tudu')->updateTudu($tudu->tuduId,
  1103. array(
  1104. 'stepid' => $tudu->stepId,
  1105. 'stepnum' => $stepNum
  1106. )
  1107. );*/
  1108. }
  1109. /**
  1110. * 更新图度后执行事件
  1111. */
  1112. public function postUpdate(Tudu_Tudu_Storage_Tudu &$tudu)
  1113. {
  1114. if ($this->updateTuduSteps($tudu)) {
  1115. return $this->getDao('Dao_Td_Tudu_Tudu')->updateTudu($tudu->tuduId,
  1116. array(
  1117. 'stepid' => $tudu->stepId,
  1118. 'stepnum' => $tudu->stepNum
  1119. )
  1120. );
  1121. }
  1122. return true;
  1123. }
  1124. /**
  1125. *
  1126. */
  1127. public function postCreate(Tudu_Tudu_Storage_Tudu &$tudu)
  1128. {
  1129. if ($tudu->flowId) {
  1130. $ret = $this->createFlowSteps($tudu);
  1131. } else {
  1132. $ret = $this->createTuduSteps($tudu);
  1133. }
  1134. if ($ret) {
  1135. return $this->getDao('Dao_Td_Tudu_Tudu')->updateTudu($tudu->tuduId,
  1136. array(
  1137. 'stepid' => $tudu->stepId,
  1138. 'stepnum' => $tudu->stepNum
  1139. )
  1140. );
  1141. }
  1142. return true;
  1143. }
  1144. /**
  1145. * 申请审批
  1146. *
  1147. * @param Tudu_Tudu_Storage_Tudu $tudu
  1148. */
  1149. public function onApply(Tudu_Tudu_Storage_Tudu &$tudu)
  1150. {
  1151. if (!$tudu->reviewer) {
  1152. return false;
  1153. }
  1154. if ($this->updateTuduSteps($tudu)) {
  1155. return $this->getDao('Dao_Td_Tudu_Tudu')->updateTudu($tudu->tuduId,
  1156. array(
  1157. 'stepid' => $tudu->stepId,
  1158. 'stepnum' => $tudu->stepNum
  1159. )
  1160. );
  1161. }
  1162. }
  1163. /**
  1164. * 公告审批
  1165. *
  1166. * @param Tudu_Tudu_Storage_Tudu $tudu
  1167. * @param boolean $isAgree
  1168. */
  1169. public function noticeReview(Tudu_Tudu_Storage_Tudu &$tudu, $isAgree)
  1170. {
  1171. // 同意
  1172. if ($isAgree) {
  1173. // 更新当前用户状态
  1174. $this->updateStepUser($tudu->tuduId, $tudu->stepId, $tudu->uniqueId, array('status' => 2));
  1175. $steps = $this->getSteps($tudu->tuduId)->toArray('stepid');
  1176. if (!isset($steps[$tudu->stepId])) {
  1177. return false;
  1178. }
  1179. $step = $steps[$tudu->stepId];
  1180. $users = $this->getStepUsers($tudu->tuduId, $tudu->stepId);
  1181. // 当前审批人
  1182. $nextUser = false;
  1183. $nextStep = true;
  1184. $nextIndex = null;
  1185. $currIndex = null;
  1186. $reviewer = array();
  1187. $tudu->sameReview = false;
  1188. foreach ($users as $user) {
  1189. if ($user['uniqueid'] == $tudu->uniqueId) {
  1190. $currentUser = $user;
  1191. $currIndex = $user['processindex'];
  1192. if (empty($reviewer)) {
  1193. $nextUser = true;
  1194. }
  1195. continue ;
  1196. }
  1197. // 还有用户在审核中,跳过流程
  1198. if ($user['status'] == 1) {
  1199. list ($userName, $trueName) = explode(' ', $user['userinfo']);
  1200. $reviewer[] = array('email' => $userName, 'truename' => $trueName);
  1201. $nextStep = false;
  1202. $nextUser = false;
  1203. $tudu->sameReview = true;
  1204. }
  1205. // 转到本步骤后续执行人
  1206. if ($nextUser) {
  1207. if ($user['status'] == 2) {
  1208. continue ;
  1209. }
  1210. if (null === $nextIndex) {
  1211. $nextIndex = $user['processindex'];
  1212. }
  1213. if (null !== $nextIndex && $user['processindex'] != $nextIndex) {
  1214. break ;
  1215. }
  1216. if (null !== $currIndex && $currIndex == $user['processindex']) {
  1217. break ;
  1218. }
  1219. list ($userName, $trueName) = explode(' ', $user['userinfo']);
  1220. $reviewer[] = array('email' => $userName, 'truename' => $trueName);
  1221. $this->updateStepUser($tudu->tuduId, $tudu->stepId, $user['uniqueid'], array('status' => 1));
  1222. $nextStep = false;
  1223. }
  1224. }
  1225. if (count($reviewer)) {
  1226. $tudu->reviewer = array($reviewer);
  1227. }
  1228. // 下一步即发送公告
  1229. if ($nextStep) {
  1230. // 清空审批人
  1231. $tudu->reviewer = null;
  1232. // 发送公告到接收人
  1233. $tudu->cc = Tudu_Tudu_Storage::formatRecipients($tudu->cc);
  1234. $tudu->stepId = $step['nextstepid'];
  1235. }
  1236. // 不同意
  1237. } else {
  1238. // 更新当前用户状态
  1239. $this->updateStepUser($tudu->tuduId, $tudu->stepId, $tudu->uniqueId, array('status' => 3));
  1240. $steps = $this->getSteps($tudu->tuduId)->toArray('stepid');
  1241. if (!isset($steps[$tudu->stepId])) {
  1242. return false;
  1243. }
  1244. $step = $steps[$tudu->stepId];
  1245. $tudu->stepId = $step['prevstepid'];
  1246. }
  1247. return true;
  1248. }
  1249. /**
  1250. * 审批
  1251. *
  1252. * @param $tudu
  1253. */
  1254. public function onReview(Tudu_Tudu_Storage_Tudu &$tudu, $isAgree)
  1255. {
  1256. // 公告审批处理
  1257. if ($tudu->type == 'notice') {
  1258. return $this->noticeReview($tudu, $isAgree);
  1259. }
  1260. // 更新当前用户状态
  1261. if ($isAgree) {
  1262. $this->updateStepUser($tudu->tuduId, $tudu->stepId, $tudu->uniqueId, array('status' => 2));
  1263. $tudu->currentStepStatus = false;
  1264. // 更新图度后续步骤
  1265. if ($tudu->reviewer || $tudu->to) {
  1266. $this->updateTuduSteps($tudu);
  1267. // 直接同意
  1268. } else {
  1269. $steps = $this->getSteps($tudu->tuduId)->toArray('stepid');
  1270. if (!isset($steps[$tudu->stepId])) {
  1271. return false;
  1272. }
  1273. $step = $steps[$tudu->stepId];
  1274. $users = $this->getStepUsers($tudu->tuduId, $tudu->stepId);
  1275. // 当前审批人
  1276. $nextUser = false;
  1277. $nextStep = true;
  1278. $nextIndex = null;
  1279. $currIndex = null;
  1280. $reviewer = array();
  1281. $tudu->sameReview = false;//var_dump($users);
  1282. foreach ($users as $user) {
  1283. if ($user['uniqueid'] == $tudu->uniqueId) {
  1284. $currentUser = $user;
  1285. $currIndex = $user['processindex'];
  1286. if (empty($reviewer)) {
  1287. $nextUser = true;
  1288. }
  1289. continue ;
  1290. } elseif (null !== $currIndex && $user['processindex'] == $currIndex && $user['status'] > 1) {
  1291. continue ;
  1292. }
  1293. // 还有用户在审核中,跳过流程
  1294. if ($user['status'] == 1) {
  1295. list ($userName, $trueName) = explode(' ', $user['userinfo']);
  1296. $reviewer[] = array('email' => $userName, 'truename' => $trueName);
  1297. $nextStep = false;
  1298. $nextUser = false;
  1299. $tudu->sameReview = true;
  1300. }
  1301. // 转到本步骤后续执行人
  1302. if ($nextUser) {
  1303. if (null === $nextIndex) {
  1304. $nextIndex = $user['processindex'];
  1305. }
  1306. if (null !== $nextIndex && $user['processindex'] != $nextIndex) {
  1307. break ;
  1308. }
  1309. if (null !== $currIndex && $currIndex == $user['processindex']) {
  1310. break ;
  1311. }
  1312. list ($userName, $trueName) = explode(' ', $user['userinfo']);
  1313. $reviewer[] = array('email' => $userName, 'truename' => $trueName);
  1314. $this->updateStepUser($tudu->tuduId, $tudu->stepId, $user['uniqueid'], array('status' => 1));
  1315. $nextStep = false;
  1316. }
  1317. }
  1318. if (count($reviewer)) {
  1319. $tudu->reviewer = array($reviewer);
  1320. }
  1321. // 下一步骤
  1322. if ($nextStep) {
  1323. if ($step['nextstepid'] == '^end') {
  1324. $tudu->stepId = $step['nextstepid'];
  1325. return false;
  1326. }
  1327. if (!isset($steps[$step['nextstepid']])) {
  1328. return false;
  1329. }
  1330. $tudu->currentStepStatus = true; //当前步骤是否已完结
  1331. $updateStatus = false;
  1332. $nextStep = $steps[$step['nextstepid']];
  1333. $nextIndex = null;
  1334. $nextStepUsers = $this->getStepUsers($tudu->tuduId, $nextStep['stepid']);
  1335. // 下一步仍然是审批步骤
  1336. if ($nextStep['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE) {
  1337. foreach ($nextStepUsers as $item) {
  1338. if (null === $nextIndex) {
  1339. $nextIndex = $item['processindex'];
  1340. }
  1341. if (null !== $nextIndex && $item['processindex'] != $nextIndex) {
  1342. break;
  1343. }
  1344. list ($userName, $trueName) = explode(' ', $item['userinfo']);
  1345. $reviewer[] = array('email' => $userName, 'truename' => $trueName);
  1346. if ($tudu->flowId && $item['status'] > 1) {
  1347. $updateStatus = true;
  1348. $this->updateStepUser($tudu->tuduId, $nextStep['stepid'], $item['uniqueid'], array('status' => 1));
  1349. }
  1350. }
  1351. $tudu->reviewer = array($reviewer);
  1352. // 下一步是执行
  1353. } else {
  1354. $users = array();
  1355. foreach ($nextStepUsers as $item) {
  1356. list($email, $trueName) = explode(' ', $item['userinfo']);
  1357. $users[$email] = array(
  1358. 'email' => $email,
  1359. 'truename' => $trueName,
  1360. 'percent' => (int) $item['percent']
  1361. );
  1362. if ($tudu->flowId && $item['status'] > 1) {
  1363. $updateStatus = true;
  1364. $manager = Tudu_Tudu_Manager::getInstance();
  1365. $manager->updateProgress($tudu->tuduId, $item['uniqueid'], 0);
  1366. if ($tudu->parentId) {
  1367. $manager->calParentsProgress($tudu->parentId);
  1368. }
  1369. $this->updateStepUser($tudu->tuduId, $nextStep['stepid'], $item['uniqueid'], array('status' => 1));
  1370. }
  1371. }
  1372. $tudu->reviewer = null;
  1373. $tudu->to = Tudu_Tudu_Storage::formatRecipients($users);
  1374. }
  1375. if ($tudu->flowId && $updateStatus) {
  1376. $this->updateStep($tudu->tuduId, $nextStep['stepid'], array('status' => 0));
  1377. }
  1378. $tudu->stepId = $step['nextstepid'];
  1379. }
  1380. }
  1381. } else {
  1382. if ($tudu->flowId) {
  1383. return $this->flowReviewReject($tudu);
  1384. }
  1385. $this->updateStepUser($tudu->tuduId, $tudu->stepId, $tudu->uniqueId, array('status' => 3));
  1386. // 审批拒绝均打回发起人
  1387. $tudu->stepId = '^head';
  1388. $tudu->to = Tudu_Tudu_Storage::formatRecipients($tudu->from);
  1389. /*
  1390. $steps = $this->getSteps($tudu->tuduId)->toArray('stepid');
  1391. if (!isset($steps[$tudu->stepId])) {
  1392. return false;
  1393. }
  1394. $step = $steps[$tudu->stepId];
  1395. $prevId = $step['prevstepid'];
  1396. $toStepId = $prevId;
  1397. do {
  1398. if (!isset($steps[$prevId])) {
  1399. $prevId = '^head';
  1400. break ;
  1401. }
  1402. $prev = $steps[$prevId];
  1403. if ($prev['type'] == 0) {
  1404. break ;
  1405. }
  1406. $prevId = $prev['prevstepid'];
  1407. $toStepId = $prev['stepid'];
  1408. if ($prevId == '^head') {
  1409. break ;
  1410. }
  1411. } while ($prev['type'] == 0);
  1412. $tudu->stepId = $toStepId;
  1413. if ($toStepId == '^head' || $toStepId == '^trunk') {
  1414. $tudu->to = Tudu_Tudu_Storage::formatRecipients($tudu->from);
  1415. } else {
  1416. $users = $this->getStepUsers($tudu->tuduId, $toStepId);
  1417. $to = array();
  1418. foreach ($users as $item) {
  1419. $to[] = $item['userinfo'];
  1420. }
  1421. $tudu->to = Tudu_Tudu_Storage::formatRecipients(implode("\n", $to));
  1422. }
  1423. */
  1424. }
  1425. }
  1426. /**
  1427. * 工作流审批拒绝操作
  1428. *
  1429. * @param Tudu_Tudu_Storage_Tudu $tudu
  1430. */
  1431. public function flowReviewReject(Tudu_Tudu_Storage_Tudu &$tudu)
  1432. {
  1433. // 取得步骤
  1434. $steps = $this->getSteps($tudu->tuduId)->toArray('stepid');
  1435. $this->updateStepUser($tudu->tuduId, $tudu->stepId, $tudu->uniqueId, array('status' => 3));
  1436. // 当前步骤不存在,则终止流程
  1437. if (!isset($steps[$tudu->stepId])) {
  1438. $tudu->stepId = self::NODE_BREAK;
  1439. $this->preflowRejectUsers($tudu);
  1440. return true;
  1441. }
  1442. $step = $steps[$tudu->stepId];
  1443. $prevId = $step['prevstepid'];
  1444. // 当前步骤的上一步骤是终止流程
  1445. if ($prevId == self::NODE_BREAK) {
  1446. $tudu->stepId = self::NODE_BREAK;
  1447. $this->preflowRejectUsers($tudu);
  1448. return true;
  1449. }
  1450. // 打回到开始
  1451. if ($prevId == self::NODE_HEAD) {
  1452. $tudu->stepId = self::NODE_HEAD;
  1453. $this->preflowRejectUsers($tudu);
  1454. return true;
  1455. }
  1456. // 打回, 步骤不存在,则终止流程
  1457. if (!isset($steps[$prevId])) {
  1458. $tudu->stepId = self::NODE_BREAK;
  1459. $this->preflowRejectUsers($tudu);
  1460. return true;
  1461. }
  1462. // 取得打回步骤信息
  1463. $prev = $steps[$prevId];
  1464. $updateStatus = false;
  1465. $nextIndex = null;
  1466. $users = $this->getStepUsers($tudu->tuduId, $prev['stepid']);
  1467. if ($prev['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE) {
  1468. $reviewer = array();
  1469. foreach ($users as $item) {
  1470. if (null === $nextIndex) {
  1471. $nextIndex = $item['processindex'];
  1472. }
  1473. if (null !== $nextIndex && $item['processindex'] != $nextIndex) {
  1474. break;
  1475. }
  1476. list ($userName, $trueName) = explode(' ', $item['userinfo']);
  1477. $reviewer[] = array('email' => $userName, 'truename' => $trueName);
  1478. if ($item['status'] > 1) {
  1479. $updateStatus = true;
  1480. $this->updateStepUser($tudu->tuduId, $prev['stepid'], $item['uniqueid'], array('status' => 1));
  1481. }
  1482. }
  1483. $tudu->reviewer = array($reviewer);
  1484. } else {
  1485. $to = array();
  1486. foreach ($users as $item) {
  1487. list($email, $trueName) = explode(' ', $item['userinfo']);
  1488. $to[$email] = array(
  1489. 'email' => $email,
  1490. 'truename' => $trueName,
  1491. 'percent' => (int) $item['percent']
  1492. );
  1493. if ($item['status'] > 1) {
  1494. $this->updateStepUser($tudu->tuduId, $prev['stepid'], $item['uniqueid'], array('status' => 1));
  1495. $manager = Tudu_Tudu_Manager::getInstance();
  1496. $manager->updateProgress($tudu->tuduId, $item['uniqueid'], 0);
  1497. if ($tudu->parentId) {
  1498. $manager->calParentsProgress($tudu->parentId);
  1499. }
  1500. $updateStatus = true;
  1501. }
  1502. }
  1503. $tudu->reviewer = null;
  1504. $tudu->to = Tudu_Tudu_Storage::formatRecipients($to);
  1505. }
  1506. if ($updateStatus) {
  1507. $this->updateStep($tudu->tuduId, $prev['stepid'], array('status' => 0));
  1508. }
  1509. $tudu->stepId = $prev['stepid'];
  1510. $this->preflowRejectUsers($tudu);
  1511. return true;
  1512. }
  1513. /**
  1514. *
  1515. * @param $tudu
  1516. */
  1517. public function preflowRejectUsers(Tudu_Tudu_Storage_Tudu &$tudu)
  1518. {
  1519. if ($tudu->stepId == '^head' || $tudu->stepId == '^break') {
  1520. $tudu->to = Tudu_Tudu_Storage::formatRecipients($tudu->from);
  1521. } else {
  1522. $users = $this->getStepUsers($tudu->tuduId, $tudu->stepId);
  1523. $to = array();
  1524. foreach ($users as $item) {
  1525. $to[] = $item['userinfo'];
  1526. }
  1527. $tudu->to = Tudu_Tudu_Storage::formatRecipients(implode("\n", $to));
  1528. }
  1529. return true;
  1530. }
  1531. /**
  1532. *
  1533. * @param $tudu
  1534. */
  1535. public function onSend(Tudu_Tudu_Storage_Tudu &$tudu)
  1536. {
  1537. //$this->flowToStep($tudu->tuduId, $tudu->stepId);
  1538. return $this->getDao('Dao_Td_Tudu_Tudu')->updateTudu($tudu->tuduId,
  1539. array(
  1540. 'stepid' => $tudu->stepId,
  1541. 'stepnum' => $tudu->stepNum
  1542. )
  1543. );
  1544. }
  1545. /**
  1546. * 转发图度
  1547. *
  1548. * @param $tudu
  1549. */
  1550. public function onForward(Tudu_Tudu_Storage_Tudu &$tudu)
  1551. {
  1552. if ($tudu->flowId) {
  1553. return $this->forwardTuduFlow($tudu);
  1554. }
  1555. if ($this->updateTuduSteps($tudu, false)) {
  1556. return $this->getDao('Dao_Td_Tudu_Tudu')->updateTudu($tudu->tuduId,
  1557. array(
  1558. 'stepid' => $tudu->stepId,
  1559. 'stepnum' => $tudu->stepNum
  1560. )
  1561. );
  1562. }
  1563. }
  1564. /**
  1565. * 处理工作流任务的转发
  1566. *
  1567. * @param Tudu_Tudu_Storage_Tudu $tudu
  1568. */
  1569. public function forwardTuduFlow(Tudu_Tudu_Storage_Tudu &$tudu)
  1570. {
  1571. /* @var $daoStep Dao_Td_Tudu_Flow */
  1572. $daoStep = Tudu_Dao_Manager::getDao('Dao_Td_Tudu_Step', Tudu_Dao_Manager::DB_TS);
  1573. $steps = $daoStep->getSteps(array('tuduid' => $tudu->tuduId))->toArray('stepid');
  1574. if (!isset($steps[$tudu->stepId])) {
  1575. return ;
  1576. }
  1577. $currentStep = $steps[$tudu->stepId];
  1578. $nextStep = isset($steps[$currentStep['nextstepid']]) ? $steps[$currentStep['nextstepid']] : null;
  1579. $to = $tudu->to;
  1580. $fistStepId = null;
  1581. $lastStepId = null;
  1582. $count = 0;
  1583. $steps = array();
  1584. $to = array($to);
  1585. foreach ($to as $arr) {
  1586. $stepId = Dao_Td_Tudu_Step::getStepId();
  1587. $step = array(
  1588. 'orgid' => $tudu->orgId,
  1589. 'tuduid' => $tudu->tuduId,
  1590. 'uniqueid' => $tudu->uniqueId,
  1591. 'stepid' => $stepId,
  1592. 'prevstepid' => $tudu->stepId,
  1593. 'nextstepid' => $currentStep['nextstepid'],
  1594. 'type' => Dao_Td_Tudu_Step::TYPE_EXECUTE,
  1595. 'ordernum' => $currentStep['ordernum'] + $count + 1,
  1596. 'createtime' => time()
  1597. );
  1598. $users = array();
  1599. foreach ($arr as $userName => $u) {
  1600. $users[] = array(
  1601. 'email' => $u['email'],
  1602. 'truename' => $u['truename']
  1603. );
  1604. }
  1605. $step['users'] = $users;
  1606. if ($count == 0) {
  1607. $firstStepId = $stepId;
  1608. }
  1609. $count ++;
  1610. $steps[] = $step;
  1611. }
  1612. $lastStepId = $stepId;
  1613. $daoStep->updateStep($tudu->tuduId, $currentStep['stepid'], array('nextstepid' => $stepId));
  1614. $daoStep->updateStep($tudu->tuduId, $currentStep['nextstepid'], array('prevstepid' => $stepId));
  1615. if (null != $nextStep) {
  1616. $daoStep->updateNextStepsOrder($tudu->tuduId, $nextStep['ordernum'], $count);
  1617. }
  1618. foreach ($steps as $step) {
  1619. if ($this->createStep($step)) {
  1620. $recipients = $this->prepareRecipients($tudu->orgId, $tudu->uniqueId, $step['users']);
  1621. $processIndex = $step['type'] == Dao_Td_Tudu_Step::TYPE_EXAMINE ? 0 : null;
  1622. $this->addStepUsers($tudu->tuduId, $step['stepid'], $recipients, $processIndex);
  1623. }
  1624. }
  1625. /* @var $daoStep Dao_Td_Tudu_Tudu */
  1626. //$daoTudu = Tudu_Dao_Manager::getDao('Dao_Td_Tudu_Tudu', Tudu_Dao_Manager::DB_TS);
  1627. //$daoTudu->updateTudu($tudu->tuduId, array('stepid' => $firstStepId));
  1628. $tudu->stepId = $firstStepId;
  1629. }
  1630. /**
  1631. * 获取部门列表
  1632. *
  1633. * @param string $orgId
  1634. */
  1635. protected function _getDepartments($orgId)
  1636. {
  1637. if (null === $this->_depts) {
  1638. /* @var Dao_Md_Department_Department */
  1639. $daoDepts = $this->getDao('Dao_Md_Department_Department', Tudu_Dao_Manager::DB_MD);
  1640. $this->_depts = $daoDepts->getDepartments(array(
  1641. 'orgid' => $orgId
  1642. ))->toArray('deptid');
  1643. }
  1644. return $this->_depts;
  1645. }
  1646. /**
  1647. *
  1648. * @param string $userId
  1649. * @param string $deptId
  1650. */
  1651. protected function _getUpper($email, $orgId, $deptId)
  1652. {
  1653. list($userId, ) = explode('@', $email);
  1654. $depts = $this->_getDepartments($orgId);
  1655. if (empty($depts[$deptId])) {
  1656. return null;
  1657. }
  1658. $dept = $depts[$deptId];
  1659. if (empty($dept['moderators'])) {
  1660. return null;
  1661. }
  1662. $ret = array();
  1663. // 是当前部门负责人
  1664. if (in_array($userId, $dept['moderators']) && $deptId != '^root') {
  1665. $dept = $depts[$dept['parentid']];
  1666. }
  1667. foreach ($dept['moderators'] as $m) {
  1668. $ret[] = $m;
  1669. }
  1670. return $ret;
  1671. }
  1672. }