Merge branch 'seeddms-6.0.x-workflow' into seeddms-6.0.x

This commit is contained in:
Uwe Steinmann 2018-04-06 06:39:29 +02:00
commit 659a62e133
11 changed files with 270 additions and 98 deletions

View File

@ -14,6 +14,8 @@
the uploader
- add scheduler
- add hook showVersionComment in out.ViewDocument.php
- Various minor corrections of database tables tblWorkflowLog and
tblWorkflowDocumentContent
- merge changes up to 5.1.6
--------------------------------------------------------------------------------

View File

@ -2270,11 +2270,14 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */
return false;
}
/* Will be deleted automatically when record will be deleted
* from tblWorkflowDocumentContent
$queryStr = "DELETE FROM `tblWorkflowLog` WHERE `document` = '". $this->getID() ."' AND `version` = '" . $version->_version."'";
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
}
*/
// remove document files attached to version
$res = $this->getDocumentFiles($version->_version);
@ -5407,7 +5410,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
$db = $this->_document->_dms->getDB();
if($this->_workflow) {
$queryStr = "UPDATE `tblWorkflowDocumentContent` set `state`=". $state->getID() ." WHERE `workflow`=". intval($this->_workflow->getID()). " AND `document`=". intval($this->_document->getID()) ." AND version=". intval($this->_version) ."";
$queryStr = "UPDATE `tblWorkflowDocumentContent` set `state`=". $state->getID() ." WHERE `id`=". $this->_workflow['id'];
if (!$db->getResult($queryStr)) {
return false;
}
@ -5434,9 +5437,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
if (!$this->_workflowState) {
$queryStr=
"SELECT b.* FROM `tblWorkflowDocumentContent` a LEFT JOIN `tblWorkflowStates` b ON a.`state` = b.id WHERE `workflow`=". intval($this->_workflow->getID())
." AND a.`version`='".$this->_version
."' AND a.`document` = '". $this->_document->getID() ."' ";
"SELECT b.* FROM `tblWorkflowDocumentContent` a LEFT JOIN `tblWorkflowStates` b ON a.`state` = b.id WHERE `a`.`id`=". $this->_workflow['id'];
$recs = $db->getResultArray($queryStr);
if (is_bool($recs) && !$recs)
return false;
@ -5455,6 +5456,9 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
$db = $this->_document->_dms->getDB();
$this->getWorkflow();
if($this->_workflow)
return false;
if($workflow && is_object($workflow)) {
$db->startTransaction();
$initstate = $workflow->getInitState();
@ -5463,7 +5467,11 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
$db->rollbackTransaction();
return false;
}
$this->_workflow = $workflow;
$this->getWorkflow();
if($workflow->getID() != $this->_workflow['workflow']->getID()) {
$db->rollbackTransaction();
return false;
}
if(!$this->setStatus(S_IN_WORKFLOW, "Added workflow '".$workflow->getName()."'", $user)) {
$db->rollbackTransaction();
return false;
@ -5471,15 +5479,19 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
$db->commitTransaction();
return true;
}
return true;
return false;
} /* }}} */
/**
* Get workflow assigned to the document content
*
* The method returns the last workflow if one was assigned.
* If a the document version is in a sub workflow, it will have
* If the document version is in a sub workflow, it will have
* a never date and therefore will be found first.
* The methods also sets $this->_workflow['id'] and
* $this->_workflow['parent']. $this->_workflow['id'] is the
* id from table tblWorkflowDocumentContent which is used to
* get log entries for this workflow.
*
* @return object/boolean an object of class SeedDMS_Core_Workflow
* or false in case of error, e.g. the version has not a workflow
@ -5489,18 +5501,19 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
if (!isset($this->_workflow)) {
$queryStr=
"SELECT b.* FROM `tblWorkflowDocumentContent` a LEFT JOIN `tblWorkflows` b ON a.`workflow` = b.id WHERE a.`version`='".$this->_version
"SELECT a.id as wdcid, a.parent, b.* FROM `tblWorkflowDocumentContent` a LEFT JOIN `tblWorkflows` b ON a.`workflow` = b.id WHERE a.`version`='".$this->_version
."' AND a.`document` = '". $this->_document->getID() ."' "
." AND a.`state` IS NOT NULL"
." ORDER BY `date` DESC LIMIT 1";
$recs = $db->getResultArray($queryStr);
if (is_bool($recs) && !$recs)
return false;
if(!$recs)
return false;
$this->_workflow = new SeedDMS_Core_Workflow($recs[0]['id'], $recs[0]['name'], $this->_document->_dms->getWorkflowState($recs[0]['initstate']), $recs[0]["layoutdata"]);
$this->_workflow->setDMS($this->_document->_dms);
$this->_workflow = array('id'=>(int)$recs[0]['wdcid'], 'parent'=>(int)$recs[0]['parent'], 'workflow'=>new SeedDMS_Core_Workflow($recs[0]['id'], $recs[0]['name'], $this->_document->_dms->getWorkflowState($recs[0]['initstate']), $recs[0]["layoutdata"]));
$this->_workflow['workflow']->setDMS($this->_document->_dms);
}
return $this->_workflow;
return $this->_workflow['workflow'];
} /* }}} */
/**
@ -5516,10 +5529,18 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
function rewriteWorkflowLog($workflowlog) { /* {{{ */
$db = $this->_document->_dms->getDB();
/* Get the workflowdocumentcontent */
$queryStr = "SELECT `id` FROM `tblWorkflowDocumentContent` WHERE `tblWorkflowDocumentContent`.`document` = '". $this->_document->getID() ."' AND `tblWorkflowDocumentContent`.`version` = '". $this->_version ."'";
$recs = $db->getResultArray($queryStr);
if (is_bool($recs) && !$recs)
return false;
if (!$recs)
return false;
$db->startTransaction();
/* First, remove the old entries */
$queryStr = "DELETE FROM `tblWorkflowLog` WHERE `tblWorkflowLog`.`document` = '". $this->_document->getID() ."' AND `tblWorkflowLog`.`version` = '". $this->_version ."'";
$queryStr = "DELETE FROM `tblWorkflowLog` WHERE `tblWorkflowLog`.`workflowdocumentcontent` IN (SELECT `id` FROM `tblWorkflowDocumentContent` WHERE `tblWorkflowDocumentContent`.`document` = '". $this->_document->getID() ."' AND `tblWorkflowDocumentContent`.`version` = '". $this->_version ."')";
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
@ -5532,8 +5553,8 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
$db->rollbackTransaction();
return false;
}
$queryStr = "INSERT INTO `tblWorkflowLog` (`document`, `version`, `workflow`, `transition`, `comment`, `date`, `userid`) ".
"VALUES ('".$this->_document->getID() ."', '".(int) $this->_version."', '".(int) $log['workflow']->getID()."', '".(int) $log['transition']->getID()."', ".$db->qstr($log['comment']) .", ".$db->qstr($log['date']).", ".$log['user']->getID().")";
$queryStr = "INSERT INTO `tblWorkflowLog` (`workflowdocumentcontent`, `transition`, `comment`, `date`, `userid`) ".
"VALUES ('".$recs[0]['id'] ."', '".(int) $log['transition']->getID()."', ".$db->qstr($log['comment']) .", ".$db->qstr($log['date']).", ".$log['user']->getID().")";
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
@ -5558,15 +5579,16 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
if (!isset($this->_workflow)) {
return true;
}
$workflow = $this->_workflow['workflow'];
$db->startTransaction();
$queryStr = "DELETE from `tblWorkflowLog` WHERE `document` = ". $this->_document->getID() ." AND `version` = ".$this->_version." AND `workflow` = ".$this->_workflow->getID();
$queryStr = "DELETE from `tblWorkflowLog` WHERE `workflowdocumentcontent` = ".$this->_workflow['id'];
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
}
$this->setWorkflowState($this->_workflow->getInitState());
$this->setWorkflowState($workflow->getInitState());
$db->commitTransaction();
return true;
@ -5578,7 +5600,8 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
* Fully removing a workflow including entries in the workflow log is
* only allowed if the workflow is still its initial state.
* At a later point of time only unlinking the document from the
* workflow is allowed. It will keep any log entries.
* workflow is allowed. It will keep any log entries and set the state
* to NULL.
* A workflow is unlinked from a document when enterNextState()
* succeeds.
*
@ -5600,27 +5623,35 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
return true;
}
if(SeedDMS_Core_DMS::checkIfEqual($this->_workflow->getInitState(), $this->getWorkflowState()) || $unlink == true) {
$workflow = $this->_workflow['workflow'];
if(SeedDMS_Core_DMS::checkIfEqual($workflow->getInitState(), $this->getWorkflowState()) || $unlink == true) {
$db->startTransaction();
$queryStr=
"DELETE FROM `tblWorkflowDocumentContent` WHERE "
."`version`='".$this->_version."' "
." AND `document` = '". $this->_document->getID() ."' "
." AND `workflow` = '". $this->_workflow->getID() ."' ";
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
}
if(!$unlink) {
if($unlink) {
$queryStr=
"DELETE FROM `tblWorkflowLog` WHERE "
."`version`='".$this->_version."' "
." AND `document` = '". $this->_document->getID() ."' "
." AND `workflow` = '". $this->_workflow->getID() ."' ";
"UPDATE `tblWorkflowDocumentContent` SET `state` = NULL WHERE `id`=".$this->_workflow['id'];
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
}
} else {
$queryStr=
"DELETE FROM `tblWorkflowDocumentContent` WHERE `id`=".$this->_workflow['id'];
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
}
/* will be deleted automatically when tblWorkflowDocumentContent is deleted
$queryStr=
"DELETE FROM `tblWorkflowLog` WHERE "
."`version`='".$this->_version."' "
." AND `document` = '". $this->_document->getID() ."' "
." AND `workflow` = '". $workflow->getID() ."' ";
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
}
*/
}
$this->_workflow = null;
$this->_workflowState = null;
@ -5644,19 +5675,19 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
if(!$this->_workflow)
return false;
if(!$this->_workflow['parent'])
return false;
$queryStr=
"SELECT * FROM `tblWorkflowDocumentContent` WHERE "
."`version`='".$this->_version."' "
." AND `document` = '". $this->_document->getID() ."' "
." AND `workflow` = '". $this->_workflow->getID() ."' ";
"SELECT * FROM `tblWorkflowDocumentContent` WHERE `parent`=".$this->_workflow['parent'];
$recs = $db->getResultArray($queryStr);
if (is_bool($recs) && !$recs)
return false;
if(!$recs)
return false;
if($recs[0]['parentworkflow'])
return $this->_document->_dms->getWorkflow($recs[0]['parentworkflow']);
if($recs[0]['workflow'])
return $this->_document->_dms->getWorkflow((int)$recs[0]['workflow']);
return false;
} /* }}} */
@ -5680,11 +5711,11 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
if($subworkflow) {
$initstate = $subworkflow->getInitState();
$queryStr = "INSERT INTO `tblWorkflowDocumentContent` (`parentworkflow`, `workflow`, `document`, `version`, `state`, `date`) VALUES (". $this->_workflow->getID(). ", ". $subworkflow->getID(). ", ". $this->_document->getID() .", ". $this->_version .", ".$initstate->getID().", ".$db->getCurrentDatetime().")";
$queryStr = "INSERT INTO `tblWorkflowDocumentContent` (`parent`, `workflow`, `document`, `version`, `state`, `date`) VALUES (". $this->_workflow['id']. ", ". $subworkflow->getID(). ", ". $this->_document->getID() .", ". $this->_version .", ".$initstate->getID().", ".$db->getCurrentDatetime().")";
if (!$db->getResult($queryStr)) {
return false;
}
$this->_workflow = $subworkflow;
$this->_workflow = array('id'=>$db->getInsertID('tblWorkflowDocumentContent'), 'parent'=>$this->_workflow['id'], 'workflow'=>$subworkflow);
return true;
}
return true;
@ -5709,30 +5740,23 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
return false;
if (isset($this->_workflow)) {
$workflow = $this->_workflow['workflow'];
$db->startTransaction();
$queryStr=
"SELECT * FROM `tblWorkflowDocumentContent` WHERE `workflow`=". intval($this->_workflow->getID())
. " AND `version`='".$this->_version
."' AND `document` = '". $this->_document->getID() ."' ";
$recs = $db->getResultArray($queryStr);
if (is_bool($recs) && !$recs) {
$db->rollbackTransaction();
return false;
}
if(!$recs) {
$db->rollbackTransaction();
return false;
}
$queryStr = "DELETE FROM `tblWorkflowDocumentContent` WHERE `workflow` =". intval($this->_workflow->getID())." AND `document` = '". $this->_document->getID() ."' AND `version` = '" . $this->_version."'";
$queryStr = "UPDATE `tblWorkflowDocumentContent` SET `state` = NULL WHERE `id` = '" . $this->_workflow['id']."'";
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
return false;
}
$this->_workflow = $this->_document->_dms->getWorkflow($recs[0]['parentworkflow']);
$this->_workflow->setDMS($this->_document->_dms);
/* Calling getWorkflow() should find the parent workflow, better check */
$parent = $this->_workflow['parent'];
unset($this->_workflow);
$this->getWorkflow();
if($this->_workflow['id'] != $parent) {
$db->rollbackTransaction();
return false;
}
if($transition) {
if(false === $this->triggerWorkflowTransition($user, $transition, $comment)) {
@ -5743,7 +5767,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
$db->commitTransaction();
}
return $this->_workflow;
return $this->_workflow['workflow'];
} /* }}} */
/**
@ -5770,7 +5794,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
/* Check if the user has already triggered the transition */
$queryStr=
"SELECT * FROM `tblWorkflowLog` WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."' AND `workflow` = ". $this->_workflow->getID(). " AND userid = ".$user->getID();
"SELECT * FROM `tblWorkflowLog` WHERE `workflowdocumentcontent` = ".$this->_workflow['id']." AND userid = ".$user->getID();
$queryStr .= " AND `transition` = ".$transition->getID();
$resArr = $db->getResultArray($queryStr);
if (is_bool($resArr) && !$resArr)
@ -5918,8 +5942,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
if(!$this->triggerWorkflowTransitionIsAllowed($user, $transition))
return false;
$state = $this->_workflowState;
$queryStr = "INSERT INTO `tblWorkflowLog` (`document`, `version`, `workflow`, `userid`, `transition`, `date`, `comment`) VALUES (".$this->_document->getID().", ".$this->_version.", " . (int) $this->_workflow->getID() . ", " .(int) $user->getID(). ", ".(int) $transition->getID().", ".$db->getCurrentDatetime().", ".$db->qstr($comment).")";
$queryStr = "INSERT INTO `tblWorkflowLog` (`workflowdocumentcontent`, `userid`, `transition`, `date`, `comment`) VALUES (".$this->_workflow['id'].", ".(int) $user->getID(). ", ".(int) $transition->getID().", ".$db->getCurrentDatetime().", ".$db->qstr($comment).")";
if (!$db->getResult($queryStr))
return false;
@ -5970,8 +5993,9 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
* the next state will be reached if one of the transitions
* leading to the given state can be processed.
*/
if($nextstate->getPreCondFunc() == '') {
$transitions = $this->_workflow->getPreviousTransitions($nextstate);
if($nextstate->getPreCondFunc() == '') {
$workflow = $this->_workflow['workflow'];
$transitions = $workflow->getPreviousTransitions($nextstate);
foreach($transitions as $transition) {
// echo "transition ".$transition->getID()." led to state ".$nextstate->getName()."<br />";
if($this->executeWorkflowTransitionIsAllowed($transition)) {
@ -5996,7 +6020,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
/* make sure the users and groups allowed to trigger the next
* transitions are also allowed to read the document
*/
$transitions = $this->_workflow->getNextTransitions($nextstate);
$transitions = $workflow->getNextTransitions($nextstate);
foreach($transitions as $tran) {
// echo "checking access for users/groups allowed to trigger transition ".$tran->getID()."<br />";
$transusers = $tran->getUsers();
@ -6035,25 +6059,28 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
/**
* Get the so far logged operations on the document content within the
* workflow
* workflow. If the document content is currently in a workflow and
* a transition is passed, then the
* log entries will be restricted on the workflow and returned as one
* dimensional list. Without a running workflow the log entries of
* all workflows in the past are returned grouped by workflow.
*
* @return array list of operations
*/
function getWorkflowLog($transition = null) { /* {{{ */
$db = $this->_document->_dms->getDB();
/*
if(!$this->_workflow)
$this->getWorkflow();
if(!$this->_workflow)
return false;
*/
$queryStr=
"SELECT * FROM `tblWorkflowLog` WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."'"; // AND `workflow` = ". $this->_workflow->getID();
if($transition)
$queryStr .= " AND `transition` = ".$transition->getID();
$queryStr .= " ORDER BY `date`";
"SELECT `a`.`id`, `a`.`userid`, `a`.`transition`, `a`.`date`, `a`.`comment`, `a`.`workflowdocumentcontent`, `b`.`version`, `b`.`document`, `b`.`workflow` FROM `tblWorkflowLog` `a` LEFT JOIN `tblWorkflowDocumentContent` `b` ON `a`.`workflowdocumentcontent` = `b`.`id` WHERE `b`.`version`='".$this->_version ."' AND `b`.`document` = '". $this->_document->getID() ."'"; // AND `workflow` = ". $this->_workflow->getID();
if($transition) {
$queryStr .= " AND `a`.`transition` = ".$transition->getID();
}
if($this->_workflow)
$queryStr .= " AND `a`.`workflowdocumentcontent` = ".$this->_workflow['id'];
$queryStr .= " ORDER BY `a`.`date`";
$resArr = $db->getResultArray($queryStr);
if (is_bool($resArr) && !$resArr)
return false;
@ -6063,7 +6090,10 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
$workflow = $this->_document->_dms->getWorkflow($resArr[$i]["workflow"]);
$workflowlog = new SeedDMS_Core_Workflow_Log($resArr[$i]["id"], $this->_document->_dms->getDocument($resArr[$i]["document"]), $resArr[$i]["version"], $workflow, $this->_document->_dms->getUser($resArr[$i]["userid"]), $workflow->getTransition($resArr[$i]["transition"]), $resArr[$i]["date"], $resArr[$i]["comment"]);
$workflowlog->setDMS($this);
$workflowlogs[$i] = $workflowlog;
if($this->_workflow && $transition)
$workflowlogs[] = $workflowlog;
else
$workflowlogs[$resArr[$i]["workflowdocumentcontent"]][] = $workflowlog;
}
return $workflowlogs;
@ -6085,7 +6115,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
return false;
$queryStr=
"SELECT * FROM `tblWorkflowLog` WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."' AND `workflow` = ". $this->_workflow->getID();
"SELECT * FROM `tblWorkflowLog` WHERE `workflowdocumentcontent` = ". $this->_workflow['id'];
$queryStr .= " ORDER BY `id` DESC LIMIT 1";
$resArr = $db->getResultArray($queryStr);
if (is_bool($resArr) && !$resArr)
@ -6111,10 +6141,11 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
function needsWorkflowAction($user) { /* {{{ */
$needwkflaction = false;
if($this->_workflow) {
$workflow = $this->_workflow['workflow'];
if (!$this->_workflowState)
$this->getWorkflowState();
$workflowstate = $this->_workflowState;
$transitions = $this->_workflow->getNextTransitions($workflowstate);
$transitions = $workflow->getNextTransitions($workflowstate);
foreach($transitions as $transition) {
if($this->triggerWorkflowTransitionIsAllowed($user, $transition)) {
$needwkflaction = true;

View File

@ -811,22 +811,18 @@ CREATE TABLE `tblWorkflowTransitionGroups` (
CREATE TABLE `tblWorkflowLog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`document` int(11) DEFAULT NULL,
`version` smallint(5) DEFAULT NULL,
`workflow` int(11) DEFAULT NULL,
`workflowdocumentcontent` int(11) NOT NULL DEFAULT '0',
`userid` int(11) DEFAULT NULL,
`transition` int(11) DEFAULT NULL,
`date` datetime NOT NULL,
`comment` text,
PRIMARY KEY (`id`),
KEY `tblWorkflowLog_document` (`document`),
KEY `tblWorkflowLog_workflow` (`workflow`),
KEY `tblWorkflowLog_userid` (`userid`),
KEY `tblWorkflowLog_transition` (`transition`),
CONSTRAINT `tblWorkflowLog_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
KEY `tblWorkflowLog_workflowdocumentcontent` (`workflowdocumentcontent`),
CONSTRAINT `tblWorkflowLog_workflowdocumentcontent` FOREIGN KEY (`workflowdocumentcontent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
CONSTRAINT `tblWorkflowLog_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
CONSTRAINT `tblWorkflowLog_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
CONSTRAINT `tblWorkflowLog_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE
CONSTRAINT `tblWorkflowLog_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
@ -836,7 +832,8 @@ CREATE TABLE `tblWorkflowLog` (
--
CREATE TABLE `tblWorkflowDocumentContent` (
`parentworkflow` int(11) DEFAULT '0',
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) DEFAULT NULL,
`workflow` int(11) DEFAULT NULL,
`document` int(11) DEFAULT NULL,
`version` smallint(5) DEFAULT NULL,
@ -847,6 +844,7 @@ CREATE TABLE `tblWorkflowDocumentContent` (
KEY `tblWorkflowDocument_state` (`state`),
CONSTRAINT `tblWorkflowDocument_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
CONSTRAINT `tblWorkflowDocument_state` FOREIGN KEY (`state`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE,
CONSTRAINT `tblWorkflowDocumentContent_parent` FOREIGN KEY (`parent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
CONSTRAINT `tblWorkflowDocument_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -536,7 +536,7 @@ CREATE TABLE "tblSessions" (
"theme" varchar(30) NOT NULL default '',
"language" varchar(30) NOT NULL default '',
"clipboard" text default NULL,
"su" INTEGER DEFAULT NULL,
"su" INTEGER DEFAULT NULL,
"splashmsg" text default NULL
) ;
@ -669,9 +669,7 @@ CREATE TABLE "tblWorkflowTransitionGroups" (
CREATE TABLE "tblWorkflowLog" (
"id" SERIAL UNIQUE,
"document" INTEGER default NULL REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
"version" INTEGER default NULL,
"workflow" INTEGER default NULL REFERENCES "tblWorkflows" ("id") ON DELETE CASCADE,
"workflowdocumentcontent" INTEGER DEFAULT NULL REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE,
"userid" INTEGER default NULL REFERENCES "tblUsers" ("id") ON DELETE CASCADE,
"transition" INTEGER default NULL REFERENCES "tblWorkflowTransitions" ("id") ON DELETE CASCADE,
"date" TIMESTAMP default NULL,
@ -685,7 +683,8 @@ CREATE TABLE "tblWorkflowLog" (
--
CREATE TABLE "tblWorkflowDocumentContent" (
"parentworkflow" INTEGER DEFAULT 0,
"id" SERIAL UNIQUE,
"parent" INTEGER DEFAULT NULL REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE,
"workflow" INTEGER DEFAULT NULL REFERENCES "tblWorkflows" ("id") ON DELETE CASCADE,
"document" INTEGER DEFAULT NULL REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
"version" INTEGER DEFAULT NULL,

View File

@ -545,7 +545,7 @@ CREATE TABLE `tblSessions` (
`theme` varchar(30) NOT NULL default '',
`language` varchar(30) NOT NULL default '',
`clipboard` text default NULL,
`su` INTEGER DEFAULT NULL,
`su` INTEGER DEFAULT NULL,
`splashmsg` text default NULL
) ;
@ -678,9 +678,7 @@ CREATE TABLE `tblWorkflowTransitionGroups` (
CREATE TABLE `tblWorkflowLog` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`document` INTEGER default NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
`version` INTEGER default NULL,
`workflow` INTEGER default NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE,
`workflowdocumentcontent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
`userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
`transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
`date` datetime NOT NULL,
@ -694,7 +692,9 @@ CREATE TABLE `tblWorkflowLog` (
--
CREATE TABLE `tblWorkflowDocumentContent` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`parentworkflow` INTEGER DEFAULT 0,
`parent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
`workflow` INTEGER DEFAULT NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE,
`document` INTEGER DEFAULT NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
`version` INTEGER DEFAULT NULL,

View File

@ -6,6 +6,30 @@ ALTER TABLE "tblUsers" ADD COLUMN "secret" varchar(50) default NULL;
ALTER TABLE "tblWorkflows" ADD COLUMN "layoutdata" text default NULL;
ALTER TABLE "tblWorkflowDocumentContent" ADD COLUMN "id" SERIAL UNIQUE;
ALTER TABLE "tblWorkflowLog" ADD COLUMN "workflowdocumentcontent" INTEGER NOT NULL DEFAULT '0';
UPDATE "tblWorkflowLog" SET "workflowdocumentcontent" = "tblWorkflowDocumentContent"."id" FROM "tblWorkflowDocumentContent" WHERE "tblWorkflowLog"."document" = "tblWorkflowDocumentContent"."document" AND "tblWorkflowLog"."version" = "tblWorkflowDocumentContent"."version" AND "tblWorkflowLog"."workflow" = "tblWorkflowDocumentContent"."workflow";
INSERT INTO "tblWorkflowDocumentContent" ("parentworkflow", "workflow", "document", "version", "state", "date") SELECT 0 AS "parentworkflow", "workflow", "document", "version", NULL AS "state", max("date") AS "date" FROM "tblWorkflowLog" WHERE "workflowdocumentcontent" = 0 GROUP BY "workflow", "document", "version";
UPDATE "tblWorkflowLog" SET "workflowdocumentcontent" = "tblWorkflowDocumentContent"."id" FROM "tblWorkflowDocumentContent" WHERE "tblWorkflowLog"."document" = "tblWorkflowDocumentContent"."document" AND "tblWorkflowLog"."version" = "tblWorkflowDocumentContent"."version" AND "tblWorkflowLog"."workflow" = "tblWorkflowDocumentContent"."workflow";
ALTER TABLE "tblWorkflowLog" ADD CONSTRAINT "tblWorkflowLog_workflowdocumentcontent" FOREIGN KEY ("workflowdocumentcontent") REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE;
ALTER TABLE "tblWorkflowDocumentContent" ADD COLUMN "parent" INTEGER DEFAULT NULL;
ALTER TABLE "tblWorkflowDocumentContent" ADD CONSTRAINT "tblWorkflowDocumentContent_parent" FOREIGN KEY ("parent") REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE;
ALTER TABLE "tblWorkflowDocumentContent" DROP COLUMN "parentworkflow";
ALTER TABLE "tblWorkflowLog" DROP COLUMN "document";
ALTER TABLE "tblWorkflowLog" DROP COLUMN "version";
ALTER TABLE "tblWorkflowLog" DROP COLUMN "workflow";
CREATE TABLE "tblUserSubstitutes" (
"id" SERIAL UNIQUE,
"user" INTEGER default null,

View File

@ -1,11 +1,44 @@
BEGIN;
ALTER TABLE `tblDocumentContent` ADD COLUMN `revisiondate` TEXT NOT NULL;
ALTER TABLE `tblDocumentContent` ADD COLUMN `revisiondate` TEXT default NULL;
ALTER TABLE `tblUsers` ADD COLUMN `secret` varchar(50) default NULL;
ALTER TABLE `tblWorkflows` ADD COLUMN `layoutdata` text default NULL;
CREATE TABLE `new_tblWorkflowDocumentContent` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`parent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
`workflow` INTEGER DEFAULT NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE,
`document` INTEGER DEFAULT NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
`version` INTEGER DEFAULT NULL,
`state` INTEGER DEFAULT NULL REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE,
`date` datetime NOT NULL
) ;
INSERT INTO `new_tblWorkflowDocumentContent` (`parent`, `workflow`, `document`, `version`, `state`, `date`) SELECT NULL as `parent`, `workflow`, `document`, `version`, `state`, `date` FROM `tblWorkflowDocumentContent`;
INSERT INTO `new_tblWorkflowDocumentContent` (`parent`, `workflow`, `document`, `version`, `state`, `date`) SELECT NULL, `a`.`workflow`, `a`.`document`, `a`.`version`, NULL AS `state`, max(`a`.`date`) FROM `tblWorkflowLog` `a` LEFT JOIN `tblWorkflowDocumentContent` `b` ON `a`.`document`=`b`.`document` AND `a`.`version`=`b`.`version` AND `a`.`workflow`=`b`.`workflow` WHERE `b`.`document` IS NULL GROUP BY `a`.`document`, `a`.`version`, `a`.`workflow`;
CREATE TABLE `new_tblWorkflowLog` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`workflowdocumentcontent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
`userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
`transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
`date` datetime NOT NULL,
`comment` text
) ;
INSERT INTO `new_tblWorkflowLog` (`id`, `workflowdocumentcontent`, `userid`, `transition`, `date`, `comment`) SELECT `a`.`id`, `b`.`id`, `a`.`userid`, `a`.`transition`, `a`.`date`, `a`.`comment` FROM `tblWorkflowLog` `a` LEFT JOIN `new_tblWorkflowDocumentContent` `b` ON `a`.`document`=`b`.`document` AND `a`.`version`=`b`.`version` AND `a`.`workflow`=`b`.`workflow` WHERE `b`.`document` IS NOT NULL;
ALTER TABLE `tblWorkflowLog` RENAME TO `old_tblWorkflowLog`;
ALTER TABLE `new_tblWorkflowLog` RENAME TO `tblWorkflowLog`;
ALTER TABLE `tblWorkflowDocumentContent` RENAME TO `old_tblWorkflowDocumentContent`;
ALTER TABLE `new_tblWorkflowDocumentContent` RENAME TO `tblWorkflowDocumentContent`;
CREATE TABLE `tblUserSubstitutes` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`user` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
@ -170,3 +203,9 @@ CREATE TABLE `tblSchedulerTask` (
UPDATE tblVersion set major=6, minor=0, subminor=0;
COMMIT;
DROP TABLE `old_tblUsers`;
DROP TABLE `old_tblWorkflowLog`;
DROP TABLE `old_tblWorkflowDocumentContent`;

View File

@ -6,6 +6,30 @@ ALTER TABLE `tblUsers` ADD COLUMN `secret` varchar(50) DEFAULT NULL AFTER `pwd`;
ALTER TABLE `tblWorkflows` ADD COLUMN `layoutdata` text DEFAULT NULL AFTER `initstate`;
ALTER TABLE `tblWorkflowDocumentContent` ADD COLUMN `id` int(11) NOT NULL AUTO_INCREMENT UNIQUE FIRST;
ALTER TABLE `tblWorkflowLog` ADD COLUMN `workflowdocumentcontent` int(11) NOT NULL DEFAULT '0' AFTER `id`;
UPDATE `tblWorkflowLog` a, `tblWorkflowDocumentContent` b SET a.`workflowdocumentcontent` = b.`id` WHERE a.`document` = b.`document` AND a.`version` = b.`version` AND a.`workflow` = b.`workflow`;
INSERT INTO `tblWorkflowDocumentContent` (`parentworkflow`, `workflow`, `document`, `version`, `state`, `date`) SELECT 0 AS `parentworkflow`, `workflow`, `document`, `version`, NULL AS `state`, max(`date`) AS `date` FROM `tblWorkflowLog` WHERE `workflowdocumentcontent` = 0 GROUP BY `workflow`, `document`, `version`;
UPDATE `tblWorkflowLog` a, `tblWorkflowDocumentContent` b SET a.`workflowdocumentcontent` = b.`id` WHERE a.`document` = b.`document` AND a.`version` = b.`version` AND a.`workflow` = b.`workflow`;
ALTER TABLE `tblWorkflowLog` ADD CONSTRAINT `tblWorkflowLog_workflowdocumentcontent` FOREIGN KEY (`workflowdocumentcontent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE;
ALTER TABLE `tblWorkflowDocumentContent` ADD COLUMN `parent` int(11) DEFAULT NULL AFTER `id`;
ALTER TABLE `tblWorkflowDocumentContent` ADD CONSTRAINT `tblWorkflowDocumentContent_parent` FOREIGN KEY (`parent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE;
ALTER TABLE `tblWorkflowDocumentContent` DROP COLUMN `parentworkflow`;
ALTER TABLE `tblWorkflowLog` DROP COLUMN `document`;
ALTER TABLE `tblWorkflowLog` DROP COLUMN `version`;
ALTER TABLE `tblWorkflowLog` DROP COLUMN `workflow`;
CREATE TABLE `tblUserSubstitutes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user` int(11) DEFAULT null,

View File

@ -0,0 +1,52 @@
Caution when you update seeddms with workflow mode `advanced`
=============================================================
The previous database layout for tracking the workflow state of a
document content was not very well done. It did not allow to run
the document through another workflow at a later time, expecially
the same workflow, e.g. for a scheduled revision of a document.
Technical details
==================
This update modifies the tables tblWorkflowDocumentContent and
tblWorkflowLog. It adds a new autoincrement field as a primary key
(id) to tblWorkflowDocumentContent and references that field in
tblWorkflowLog (workflowdocumentcontent). Till now the two tables
where linked by the fields `document`, `version`, and `workflow` which will
be replaced by the two new fields. The fields `document`, `version`, and
`workflow` will be removed from tblWorkflowLog. tblWorkflowDocumentContent
contained just the workflows currently active for a particlar document.
From now on the table will also contain finished workflows, which
will have the field `state` set to null. This allows to run even the
same workflow again and still be able to distinguish the log entries.
MySQL
------
The update process will first add the new auto incrementing, primary
field to tblWorkflowDocumentContent and a referencing field to
tblWorkflowLog. It will then fill out the referencing field with the
automatically incremented field value from tblWorkflowDocumentContent
by joining the two tables with its common fields document, version,
and workflow. This will not fill out all referencing field values,
because once a workflow has ended the record in
tblWorkflowDocumentContent will be deleted and just the records in
tblWorkflowLog are kept. The still missing records in
tblWorkflowDocumentContent for already completed workflows will be
reconstructed from the records in tblWorkflowLog which do not have a
reference to tblWorkflowDocumentContent yet. Once that is done the
referencing field in tblWorkflowLog can be filled in a second pass.
The date of the new records in tblWorkflowDocumentContent will be
taken from the last record for that workflow in tblWorkflowLog. The
state of the new records will be set null, indicating that this
workflow is no longer active.
SQLite
-------
The update process will first create new table for tblWorkflowDocumentContent
containing a new field for the primary key field. It then copies the
records from the old table to the new table. The missing records for
workflows which has been finished already are recreated from the old
table `tblWorkflowLog`. Which is then replaced by a new table having
the foreign key to table `tblWorkflowDocumentContent`.

View File

@ -46,7 +46,7 @@ class SeedDMS_View_RewindWorkflow extends SeedDMS_Bootstrap_Style {
$this->contentHeading(getMLText("rewind_workflow"));
$currentstate = $latestContent->getWorkflowState();
$wkflog = $latestContent->getWorkflowLog();
$wkflog = array_pop($latestContent->getWorkflowLog());
$workflow = $latestContent->getWorkflow();
$msg = "The document is currently in state: ".$currentstate->getName()."<br />";

View File

@ -750,11 +750,13 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style {
if($wkflogs) {
$this->contentHeading(getMLText("workflow_summary"));
$this->contentContainerStart();
foreach($wkflogs as $wkflogt) {
echo "<table class=\"table table-condensed\"><thead>";
echo "<th>".getMLText('date')."</th><th>".getMLText('action')."</th><th>".getMLText('user')."</th><th>".getMLText('comment')."</th></tr>\n";
echo "<th>".getMLText('workflow')."</th><th>".getMLText('date')."</th><th>".getMLText('action')."</th><th>".getMLText('user')."</th><th>".getMLText('comment')."</th></tr>\n";
echo "</thead><tbody>";
foreach($wkflogs as $wkflog) {
foreach($wkflogt as $wkflog) {
echo "<tr>";
echo "<td>".$wkflog->getWorkflow()->getName()."</td>";
echo "<td>".$wkflog->getDate()."</td>";
echo "<td>".$wkflog->getTransition()->getAction()->getName()."</td>";
$loguser = $wkflog->getUser();
@ -763,6 +765,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style {
echo "</tr>";
}
print "</tbody>\n</table>\n";
}
$this->contentContainerEnd();
}
}