From 06b8b423cf3f060f19566b910a38d7991df77ad3 Mon Sep 17 00:00:00 2001
From: Tim Steiner <tsteiner2@unl.edu>
Date: Fri, 5 Oct 2007 22:09:36 +0000
Subject: [PATCH] Add an action to make Approval Body Roles "watchers" of
 requests.

---
 .../ApprovalchainmanagerController.php        |  6 ++
 .../models/rows/ApprovalActionWatchers.php    | 69 +++++++++++++++++++
 application/models/rows/RequestWatcher.php    | 27 ++++++++
 .../models/tables/ApprovalActionsWatchers.php | 60 ++++++++++++++++
 .../models/tables/ApprovalBodyRoleQueues.php  | 23 +++++++
 application/models/tables/RequestWatchers.php | 61 ++++++++++++++++
 .../ApprovalActionWatchers.xhtml              | 34 +++++++++
 .../views/approval_chain_manager.xhtml        | 45 +++++++++++-
 application/views/home.xhtml                  | 62 ++++++++++++++++-
 .../javascript/approval_chain_manager.js      | 43 +++++++++++-
 10 files changed, 427 insertions(+), 3 deletions(-)
 create mode 100644 application/models/rows/ApprovalActionWatchers.php
 create mode 100644 application/models/rows/RequestWatcher.php
 create mode 100644 application/models/tables/ApprovalActionsWatchers.php
 create mode 100644 application/models/tables/RequestWatchers.php
 create mode 100644 application/views/approval_actions/ApprovalActionWatchers.xhtml

diff --git a/application/controllers/ApprovalchainmanagerController.php b/application/controllers/ApprovalchainmanagerController.php
index 257b6b05..e07882dc 100644
--- a/application/controllers/ApprovalchainmanagerController.php
+++ b/application/controllers/ApprovalchainmanagerController.php
@@ -284,11 +284,17 @@ class ApprovalChainManagerController extends Nmc_Controller_Action
     {
         $in = $this->getRequest();
         $actionName = $in->getParam(0);
+        $approvalChainId = Zend_Filter_Int::filter($in->getParam(1));
+
         $className = 'ApprovalActions' . substr($actionName, strlen('ApprovalAction'));
         $action = call_user_method('getInstance', $className);
+
+        $approvalChain = ApprovalChains::getInstance()->findOne($approvalChainId);
+
         $template = $action->getEditTemplate();
 
         $out = new Nmc_View();
+        $out->approvalChain = $approvalChain;
         $xhtml = $out->render($template);
         $dom = new DOMDocument();
         $dom->loadHTML($xhtml);
diff --git a/application/models/rows/ApprovalActionWatchers.php b/application/models/rows/ApprovalActionWatchers.php
new file mode 100644
index 00000000..a69b3ef6
--- /dev/null
+++ b/application/models/rows/ApprovalActionWatchers.php
@@ -0,0 +1,69 @@
+<?php
+
+require_once 'ApprovalActionRow/Interface.php';
+
+/**
+ * @foreignKey approvalActionId
+ * @tableClass ApprovalActionsWatchers
+ *
+ */
+class ApprovalActionWatchers extends ApprovalAction
+                             implements Application_ApprovalActionRow_Interface
+{
+
+    public function _init()
+    {
+        parent::_init();
+
+        $watchingRoleRelation = new Nmc_Db_Table_Relation_HasOne(
+            ApprovalBodyRoles::getInstance(),
+            $this,
+            'watchingRole',
+            'watchingRole',
+            true
+        );
+        $this->_registerRelation($watchingRoleRelation);
+    }
+
+    public function getResultStatusStrings()
+    {
+        return $this->getTable()->getResultStatusStrings();
+    }
+
+    public function consider(Request $request, ApprovalChain $parentChain)
+    {
+        // add watching role to ApprovalBodyRoleQueues with NULL for the ApprovalAction
+        $row = RequestWatchers::getInstance()->fetchWithRequestAndWatchingApprovalRole($request, $this->watchingRole);
+        if (!$row) {
+            $row = RequestWatchers::getInstance()->fetchNew();
+            $row->request = $request;
+            $row->watchingApprovalRole = $this->watchingRole;
+            $row->save();
+        }
+        $parentChain->advance($request);
+    }
+
+    public function updateFromForm($formData)
+    {
+        //$this->result = $formData['result'];
+        $this->watchingRole = ApprovalBodyRoles::getInstance()->findOne($formData['watchingRole']);
+    }
+
+    /**
+     * Let the action know that a user has made a decsion so that the approval
+     * process may continue.
+     *
+     * @param Request $request
+     * @param User $user
+     * @param string $decision
+     */
+    public function userMadeDecision(Request $request, User $user, $decision)
+    {
+        // since this is an Watchers action, nothing needs to happen here.
+    }
+
+    public function getUserDecision(Request $request, User $user)
+    {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/application/models/rows/RequestWatcher.php b/application/models/rows/RequestWatcher.php
new file mode 100644
index 00000000..6b369cf2
--- /dev/null
+++ b/application/models/rows/RequestWatcher.php
@@ -0,0 +1,27 @@
+<?php
+
+class RequestWatcher extends Nmc_Db_Table_Row
+{
+    public function _init()
+    {
+        parent::_init();
+
+        $requestRelation = new Nmc_Db_Table_Relation_HasOne(
+            Requests::getInstance(),
+            $this,
+            'request',
+            'request',
+            true
+        );
+        $this->_registerRelation($requestRelation);
+
+        $watchingApprovalRoleRelation = new Nmc_Db_Table_Relation_HasOne(
+            ApprovalBodyRoles::getInstance(),
+            $this,
+            'watchingApprovalRole',
+            'watchingApprovalRole',
+            true
+        );
+        $this->_registerRelation($watchingApprovalRoleRelation);
+    }
+}
diff --git a/application/models/tables/ApprovalActionsWatchers.php b/application/models/tables/ApprovalActionsWatchers.php
new file mode 100644
index 00000000..001d64ac
--- /dev/null
+++ b/application/models/tables/ApprovalActionsWatchers.php
@@ -0,0 +1,60 @@
+<?php
+
+require_once 'ApprovalActionTable/Interface.php';
+
+class ApprovalActionsWatchers extends Nmc_Db_Table
+                              implements Application_ApprovalActionTable_Interface
+{
+    protected $_primary = 'approvalActionId';
+    protected $_rowClass = 'ApprovalActionWatchers';
+
+    /**
+     * The one true instance
+     *
+     * @var ApprovalActionsWatchers
+     */
+    static protected $_instance;
+
+    /**
+     * Return the one true instance
+     *
+     * @return ApprovalActionsWatchers
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new ApprovalActionsWatchers($config);
+        }
+        return self::$_instance;
+    }
+
+    public function getActionName()
+    {
+        return 'Watchers';
+    }
+
+    public function getResultStatusStrings()
+    {
+        return array('Approved' => 'Approved',
+                     'Denied' => 'Denied');
+    }
+
+    public function getEditTemplate()
+    {
+        return 'approval_actions/ApprovalActionWatchers.xhtml';
+    }
+
+    public function fetchNew($formData = null)
+    {
+        if (!$formData) {
+            return parent::fetchNew();
+        }
+
+        $new = parent::fetchNew();
+        $new->className = 'ApprovalActionWatchers';
+        $new->watchingRole = ApprovalBodyRoles::getInstance()->findOne($formData['watchingRole']);
+
+        return $new;
+    }
+
+}
\ No newline at end of file
diff --git a/application/models/tables/ApprovalBodyRoleQueues.php b/application/models/tables/ApprovalBodyRoleQueues.php
index e6f24da7..6847148a 100755
--- a/application/models/tables/ApprovalBodyRoleQueues.php
+++ b/application/models/tables/ApprovalBodyRoleQueues.php
@@ -68,12 +68,35 @@ class ApprovalBodyRoleQueues extends Nmc_Db_Table
         $db = $this->getAdapter();
         $where   = array();
         $where[] = $db->quoteInto('request = ?', $request->getPrimaryKey());
+        $where[] = $db->quoteInto('approvalBodyRole = ?', $role->getPrimaryKey());
         $where[] = $db->quoteInto('approvalAction = ?', $action->getPrimaryKey());
+        $where   = implode(' AND ', $where);
+        return $this->fetchRow($where);
+    }
+
+    public function fetchByRequestAndRole(Request $request, ApprovalBodyRole $role, $nullOnly = true)
+    {
+        $db = $this->getAdapter();
+        $where   = array();
+        $where[] = $db->quoteInto('request = ?', $request->getPrimaryKey());
         $where[] = $db->quoteInto('approvalBodyRole = ?', $role->getPrimaryKey());
+        if ($nullOnly) {
+            $where[] = 'ISNULL(approvalAction)';
+        }
         $where   = implode(' AND ', $where);
         return $this->fetchRow($where);
     }
 
+    public function fetchByRequestAndAction(Request $request, ApprovalAction $action)
+    {
+        $db = $this->getAdapter();
+        $where   = array();
+        $where[] = $db->quoteInto('request = ?', $request->getPrimaryKey());
+        $where[] = $db->quoteInto('approvalAction = ?', $action->getPrimaryKey());
+        $where   = implode(' AND ', $where);
+        return $this->fetchAll($where);
+    }
+
     public function fetchRequestsByRole(ApprovalBodyRole $role) {
         $db = $this->getAdapter();
 
diff --git a/application/models/tables/RequestWatchers.php b/application/models/tables/RequestWatchers.php
new file mode 100644
index 00000000..90e0f221
--- /dev/null
+++ b/application/models/tables/RequestWatchers.php
@@ -0,0 +1,61 @@
+<?php
+
+class RequestWatchers extends Nmc_Db_Table
+{
+    protected $_primary = 'requestWatcherId';
+    protected $_rowClass = 'RequestWatcher';
+
+    /**
+     * The one true instance
+     *
+     * @var RequestWatchers
+     */
+    static protected $_instance;
+
+    /**
+     * Return the one true instance
+     *
+     * @return RequestWatchers
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new RequestWatchers($config);
+        }
+        return self::$_instance;
+    }
+
+    /**
+     * Return the row for the given request and role.
+     *
+     * @param Request $request
+     * @param ApprovalBodyRole $role
+     * @return RequestWatcher
+     */
+    public function fetchWithRequestAndWatchingApprovalRole(Request $request, ApprovalBodyRole $role)
+    {
+        $db = $this->getAdapter();
+        $where   = array();
+        $where[] = $db->quoteInto('request = ?', $request->getPrimaryKey());
+        $where[] = $db->quoteInto('watchingApprovalRole = ?', $role->getPrimaryKey());
+        $where   = implode(' AND ', $where);
+        return $this->fetchRow($where);
+    }
+
+    /**
+     * Return all rows with the given role
+     *
+     * @param ApprovalBodyRole $role
+     * @return Nmc_Db_Table_Rowset
+     */
+    public function fetchWithWatchingApprovalRole(ApprovalBodyRole $role)
+    {
+        $db = $this->getAdapter();
+        $where   = array();
+        $where[] = $db->quoteInto('watchingApprovalRole = ?', $role->getPrimaryKey());
+        $where   = implode(' AND ', $where);
+        return $this->fetchAll($where);
+    }
+
+
+}
\ No newline at end of file
diff --git a/application/views/approval_actions/ApprovalActionWatchers.xhtml b/application/views/approval_actions/ApprovalActionWatchers.xhtml
new file mode 100644
index 00000000..2fc263e5
--- /dev/null
+++ b/application/views/approval_actions/ApprovalActionWatchers.xhtml
@@ -0,0 +1,34 @@
+<label>
+Role to set as watchers:
+<?php
+
+$roles = $this->approvalChain->ownerBody->roles->columnToArray(
+    'name', ApprovalBodyRoles::getInstance()->getPrimaryKeyName()
+);
+
+if ($approvalAction) {
+    $watchingRole = $approvalAction->watchingRole;
+    if ($watchingRole) {
+        $watchingRoleId = $watchingRole->getPrimaryKey();
+    } else {
+        $watchingRoleId = null;
+    }
+
+
+
+    echo $this->formSelect(
+        'edit[' . $approvalAction->getPrimaryKey() . '][watchingRole]',
+        $watchingRoleId,
+        null,
+        $roles
+    );
+} else {
+    echo $this->formSelect(
+        'watchingRole',
+        null,
+        null,
+        $roles
+    );
+}
+?>
+</label>
\ No newline at end of file
diff --git a/application/views/approval_chain_manager.xhtml b/application/views/approval_chain_manager.xhtml
index 0898f509..0687ae60 100644
--- a/application/views/approval_chain_manager.xhtml
+++ b/application/views/approval_chain_manager.xhtml
@@ -23,7 +23,7 @@
     <h1>Editing Approval Chain <?php echo $this->approvalChain->name; ?></h1>
     <div id="main_details">
         <form method="post" action="/ApprovalChainManager/EditChainPost">
-        <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
+        <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey(), array('id' => 'chainId')); ?>
             <label>
                 Chain Name:
                 <?php echo $this->formText('name', $this->approvalChain->name); ?>
@@ -47,12 +47,31 @@
         </form>
     </div>
 
+
+
+
+
+
+
+
+
+
     <div id="select_links_or_actions">
         <a href="#" id="select_manage_links">Links</a>
         |
         <a href="#" id="select_manage_actions">Actions</a>
     </div>
 
+
+
+
+
+
+
+
+
+
+
     <div id="manage_links">
         <form method="post" action="/ApprovalChainManager/AddLinkPost">
             <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
@@ -86,6 +105,8 @@
             <?php echo $this->formSubmit('submit', 'Add Link', null); ?>
         </form>
 
+
+
         <form method="post" action="/ApprovalChainManager/EditLinksPost">
             <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
             <h2>Edit current Chains</h2>
@@ -143,8 +164,27 @@
             </table>
             <?php echo $this->formSubmit('submit', 'Update Links'); ?>
         </form>
+
+        <!-- svg:svg version="1.1" baseProfile="full" width="100%" height="510px">
+            <svg:rect x="5" y="5" width="500px" height="500px" fill="#cccccc" stroke="#000000" stroke-width="5px"/>
+            <svg:ellipse cx="250" cy="60" rx="100px" ry="50px" fill="#00cc00" stroke="#000000" id="ellipseFoo" />
+        </svg:svg -->
+
     </div>
 
+
+
+
+
+
+
+
+
+
+
+
+
+
     <div id="manage_actions" style="display:none;">
         <h2>Add New Action</h2>
         <form action="/ApprovalChainManager/AddActionPost" method="post">
@@ -187,6 +227,9 @@
             </div>
             <?php echo $this->formSubmit('submit', 'Create'); ?>
         </form>
+
+
+
         <h2>Edit Current Actions</h2>
         <form action="/ApprovalChainManager/EditActionPost" method="post">
             <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
diff --git a/application/views/home.xhtml b/application/views/home.xhtml
index c8256357..995f4efa 100755
--- a/application/views/home.xhtml
+++ b/application/views/home.xhtml
@@ -155,9 +155,10 @@
         <div class="bl"></div>
     </div>
     <div class="content">
-        <?php if(count($role['requests']) == 0) { ?>
+        <?php if(count($role['requests']) == 0 && count($role['watching']) == 0) { ?>
         <h2>This role currently has no requests.</h2>
         <?php } else { ?>
+        <?php if (count($role['requests']) > 0) { ?>
         <form action="/Home/SubmitDecisions" method="post">
             <?php echo $this->formSubmit('submit', 'Submit Decisions'); ?>
             <table class="course_list">
@@ -236,6 +237,65 @@
             <?php echo $this->formSubmit('submit', 'Submit Decisions'); ?>
         </form>
         <?php } ?>
+        <?php if (count($role['watching'] > 0)) { ?>
+        <table class="course_list">
+            <tr>
+                <!-- th id="check">&#160;</th -->
+                <th id="course">Course</th>
+                <th id="college">College</th>
+                <th id="type">Type</th>
+                <th id="approval_body">Approval Body</th>
+                <th id="status">Status</th>
+                <th id="view_edit">View/Edit</th>
+            </tr>
+            <?php
+            $row = 0;
+            foreach($role['watching'] as $request) {
+                $course = $request->getCourseGeneration();
+                $originalCourse = $course->getParentGeneration(true);
+                if (!$originalCourse) {
+                    $originalCourse = $course;
+                }
+            ?>
+            <tr <?php echo (++$row % 2 ? 'class="odd"' : ''); ?>>
+                <!-- td><input type="checkbox" /></td -->
+                <td><?php echo $originalCourse->subject . ' '
+                             . $originalCourse->courseNumber
+                             . $originalCourse->courseLetter; ?></td>
+                <td><?php echo $originalCourse->getHomeCollege()->name; ?></td>
+                <td><?php echo $request->type->name; ?></td>
+                <td><?php echo $request->getCurrentApprovalBody()->name; ?></td>
+                <td>
+                    <?php
+                    if ($request->complete == 'yes') {
+                        echo 'Complete - ' . $request->state;
+                    } else {
+                        echo $request->getCurrentAction()->name;
+                    }
+                    ?>                </td>
+                <td>
+                    <a href="/Request/View/<?php echo $request->getPrimaryKey(); ?>">View</a>
+                    <!-- /
+                    <a href="/Request/Load/<?php echo $request->getPrimaryKey(); ?>">Edit</a>
+                    -->
+                </td>
+                <td>
+                    <?php
+                    $lastViewTime = RequestViewTimes::getInstance()->getViewTimeForUserAndRequest($this->user, $request);
+                    $newCommentCount = RequestComments::getInstance()->fetchWithRequestAndAfterTime($request, $lastViewTime)->count();
+                    if ($newCommentCount > 0) {
+                    ?>
+                    <img src="/images/e-mail_icon1.png" alt="mail" />
+                    <?php
+                        echo $newCommentCount;
+                    }
+                    ?>
+                </td>
+          </tr>
+            <?php } ?>
+        </table>
+        <?php } ?>
+        <?php } ?>
     </div>
 </div>
 <?php } ?>
diff --git a/document_root/javascript/approval_chain_manager.js b/document_root/javascript/approval_chain_manager.js
index 86e1a096..7fa9e351 100644
--- a/document_root/javascript/approval_chain_manager.js
+++ b/document_root/javascript/approval_chain_manager.js
@@ -74,6 +74,46 @@ function loadApprovalChainManager()
     for(var i = 0; i < removeButtons.length; i++) {
         removeButtons[i].onclick = handleRemoveRecord;
     }
+
+
+
+    /*
+    //document.getElementById('ellipseFoo').onmouseover = function() {
+    //}
+
+    document.getElementById('ellipseFoo').onmouseout = function() {
+        this.setAttribute('fill', '#00cc00');
+        this.setAttribute('isMoving', 'false');
+    }
+    document.getElementById('ellipseFoo').onmousedown = function(e) {
+        this.setAttribute('fill', '#cc00cc');
+        this.setAttribute('isMoving', 'true');
+        this.setAttribute('mouseStartX', e.clientX);
+        this.setAttribute('mouseStartY', e.clientY);
+        this.setAttribute('myStartX', this.getAttribute('cx'));
+        this.setAttribute('myStartY', this.getAttribute('cy'));
+    }
+    document.getElementById('ellipseFoo').onmouseup = function() {
+        this.setAttribute('fill', '#00cc00');
+        this.setAttribute('isMoving', 'false');
+    }
+    document.getElementById('ellipseFoo').onmousemove = function(e) {
+        if (this.getAttribute('isMoving') != 'true') {
+            return;
+        } else {
+            var mouseStartX = parseInt(this.getAttribute('mouseStartX'));
+            var mouseStartY = parseInt(this.getAttribute('mouseStartY'));
+            var myStartX = parseInt(this.getAttribute('myStartX'));
+            var myStartY = parseInt(this.getAttribute('myStartY'));
+            var mouseX = parseInt(e.clientX);
+            var mouseY = parseInt(e.clientY);
+            var newX = myStartX + (mouseX - mouseStartX);
+            var newY = myStartY + (mouseY - mouseStartY);
+            this.setAttribute('cx', newX);
+            this.setAttribute('cy', newY);
+        }
+    }
+    */
 }
 
 addLoadEvent(loadApprovalChainManager);
@@ -143,7 +183,8 @@ function updateActionResults()
 
 function updateEditActionDetails()
 {
-    var url = '/ApprovalChainManager/GetActionEditXhtml/' + this.value;
+    var chainId = document.getElementById('chainId').value;
+    var url = '/ApprovalChainManager/GetActionEditXhtml/' + this.value + '/' + chainId;
     var responder = new updateEditActionDetailsAjaxResponder();
     responder.actionElement = this;
     responder.sendRequest(url);
-- 
GitLab