This commit is contained in:
liugang
2017-10-30 14:27:33 +08:00
50 changed files with 689 additions and 133 deletions
+2
View File
@@ -111,6 +111,7 @@ $filter->product->browse->cookie['storyModule'] = 'int';
$filter->product->default->cookie['lastProduct'] = 'int';
$filter->product->default->cookie['preProductID'] = 'int';
$filter->product->index->cookie['preBranch'] = 'int';
$filter->product->export->cookie['checkedItem'] = 'reg::checked';
$filter->project->default->cookie['lastProject'] = 'int';
$filter->project->default->cookie['projectMode'] = 'code';
@@ -120,6 +121,7 @@ $filter->project->task->cookie['preProjectID'] = 'int';
$filter->project->task->cookie['productBrowseParam'] = 'int';
$filter->project->task->cookie['projectTaskOrder'] = 'reg::orderBy';
$filter->project->task->cookie['windowWidth'] = 'int';
$filter->project->export->cookie['checkedItem'] = 'reg::checked';
$filter->qa->default->cookie['lastProduct'] = 'int';
$filter->qa->default->cookie['preBranch'] = 'int';
+1
View File
@@ -106,6 +106,7 @@ define('TABLE_ENTRY', '`' . $config->db->prefix . 'entry`');
define('TABLE_WEBHOOK', '`' . $config->db->prefix . 'webhook`');
define('TABLE_WEBHOOKDATAS', '`' . $config->db->prefix . 'webhookdatas`');
define('TABLE_LOG', '`' . $config->db->prefix . 'log`');
define('TABLE_SCORE', '`' . $config->db->prefix . 'score`');
if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`');
$config->objectTables['product'] = TABLE_PRODUCT;
+1
View File
@@ -545,6 +545,7 @@ class basePager
vars = vars.replace('_recTotal_', recTotal)
vars = vars.replace('_recPerPage_', recPerPage)
vars = vars.replace('_pageID_', pageID);
$.get(createLink('score', 'ajax', "method=submitPage"));
location.href=createLink('$this->moduleName', '$this->methodName', vars);
}
</script>
+2
View File
@@ -131,6 +131,7 @@ class block extends control
$this->dao->delete()->from(TABLE_BLOCK)->where('`id`')->eq($id)->andWhere('account')->eq($this->app->user->account)->andWhere('module')->eq($module)->exec();
}
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->loadModel('score')->score('block', 'set');
$this->send(array('result' => 'success'));
}
@@ -157,6 +158,7 @@ class block extends control
}
if(dao::isError()) $this->send(array('result' => 'fail'));
$this->loadModel('score')->score('block', 'set');
$this->send(array('result' => 'success'));
}
+1
View File
@@ -50,6 +50,7 @@ class blockModel extends model
$data->params = helper::jsonEncode($data->params);
$this->dao->replace(TABLE_BLOCK)->data($data)->exec();
$this->loadModel('score')->score('block', 'set');
}
/**
+7 -4
View File
@@ -85,6 +85,7 @@ class bugModel extends model
$bugID = $this->dao->lastInsertID();
$this->file->updateObjectID($this->post->uid, $bugID, 'bug');
$this->file->saveUpload('bug', $bugID);
empty($bug->case) ? $this->loadModel('score')->score('bug', 'create', $bugID) : $this->loadModel('score')->score('bug', 'createFormCase', $bug->case);
return array('status' => 'created', 'id' => $bugID);
}
return false;
@@ -199,7 +200,7 @@ class bugModel extends model
$this->dao->insert(TABLE_BUG)->data($bug)->autoCheck()->batchCheck($this->config->bug->create->requiredFields, 'notempty')->exec();
$bugID = $this->dao->lastInsertID();
$this->loadModel('score')->score('bug', 'create', $bugID);
if(!empty($data->uploadImage[$i]) and !empty($file))
{
$file['objectType'] = 'bug';
@@ -223,7 +224,7 @@ class bugModel extends model
if(is_dir($realPath)) $classFile->removeDir($realPath);
unset($_SESSION['bugImagesFile']);
}
$this->loadModel('score')->score('ajax', 'batchCreate');
return $actions;
}
@@ -654,7 +655,7 @@ class bugModel extends model
}
}
}
$this->loadModel('score')->score('ajax', 'batchEdit');
return $allChanges;
}
@@ -758,6 +759,7 @@ class bugModel extends model
->get();
$this->dao->update(TABLE_BUG)->data($bug)->where('id')->eq($bugID)->exec();
$this->loadModel('score')->score('bug', 'confirmBug', $oldBug);
if(!dao::isError()) return common::createChanges($oldBug, $bug);
}
@@ -846,7 +848,7 @@ class bugModel extends model
->checkIF($bug->resolution == 'fixed', 'resolvedBuild','notempty')
->where('id')->eq((int)$bugID)
->exec();
$this->loadModel('score')->score('bug', 'resolve', $oldBug);
/* Link bug to build and release. */
$this->linkBugToBuild($bugID, $bug->resolvedBuild);
}
@@ -1853,6 +1855,7 @@ class bugModel extends model
$condition = "`type`='bug' and account='{$this->app->user->account}'";
$this->dao->insert(TABLE_USERTPL)->data($template)->batchCheck('title, content', 'notempty')->check('title', 'unique', $condition)->exec();
$this->loadModel('score')->score('bug', 'saveTplModal', $this->dao->lastInsertID());
}
/**
+1
View File
@@ -213,6 +213,7 @@ class buildModel extends model
$buildID = $this->dao->lastInsertID();
$this->file->updateObjectID($this->post->uid, $buildID, 'build');
$this->file->saveUpload('build', $buildID);
$this->loadModel('score')->score('build', 'create', $buildID);
return $buildID;
}
}
+5 -4
View File
@@ -175,10 +175,14 @@ $lang->my->menu->dynamic = 'Dynamic|my|dynamic|';
$lang->my->menu->profile = array('link' => 'Profile|my|profile', 'alias' => 'editprofile');
$lang->my->menu->changePassword = 'Password|my|changepassword';
$lang->my->menu->manageContacts = 'Contact|my|managecontacts';
$lang->my->menu->score = array('link' => 'Score|score|browse', 'subModule' => 'score');
$lang->todo = new stdclass();
$lang->todo->menu = $lang->my->menu;
$lang->score = new stdclass();
$lang->score->menu = $lang->my->menu;
/* 产品视图设置。*/
$lang->product = new stdclass();
$lang->product->menu = new stdclass();
@@ -342,7 +346,6 @@ $lang->admin->menu->cron = array('link' => 'Cron|cron|index', 'subModule' =
$lang->admin->menu->trashes = array('link' => 'Recycle|action|trash', 'subModule' => 'action');
$lang->admin->menu->dev = array('link' => 'Develop|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
$lang->admin->menu->entry = array('link' => 'API|entry|browse', 'alias' => 'create,edit', 'subModule' => 'entry,webhook');
$lang->admin->menu->score = array('link' => 'Score|score|browse', 'subModule' => 'score');
$lang->admin->menu->sso = 'RangerTeam|admin|sso';
$lang->convert = new stdclass();
@@ -355,7 +358,6 @@ $lang->editor = new stdclass();
$lang->mail = new stdclass();
$lang->cron = new stdclass();
$lang->dev = new stdclass();
$lang->score = new stdclass();
$lang->entry = new stdclass();
$lang->webhook = new stdclass();
$lang->search = new stdclass();
@@ -370,7 +372,6 @@ $lang->custom->menu = $lang->admin->menu;
$lang->editor->menu = $lang->admin->menu;
$lang->mail->menu = $lang->admin->menu;
$lang->dev->menu = $lang->admin->menu;
$lang->score->menu = $lang->admin->menu;
$lang->entry->menu = $lang->admin->menu;
$lang->webhook->menu = $lang->admin->menu;
@@ -395,6 +396,7 @@ $lang->menugroup->testreport = 'qa';
$lang->menugroup->people = 'company';
$lang->menugroup->dept = 'company';
$lang->menugroup->todo = 'my';
$lang->menugroup->score = 'my';
$lang->menugroup->action = 'admin';
$lang->menugroup->backup = 'admin';
$lang->menugroup->cron = 'admin';
@@ -403,7 +405,6 @@ $lang->menugroup->custom = 'admin';
$lang->menugroup->editor = 'admin';
$lang->menugroup->mail = 'admin';
$lang->menugroup->dev = 'admin';
$lang->menugroup->score = 'admin';
$lang->menugroup->entry = 'admin';
$lang->menugroup->webhook = 'admin';
+1
View File
@@ -25,6 +25,7 @@ $lang->my->menuOrder[40] = 'myProject';
$lang->my->menuOrder[45] = 'dynamic';
$lang->my->menuOrder[50] = 'profile';
$lang->my->menuOrder[55] = 'changePassword';
$lang->my->menuOrder[60] = 'score';
$lang->todo->menuOrder = $lang->my->menuOrder;
/* product menu order. */
+8 -7
View File
@@ -167,18 +167,22 @@ $lang->my->menu->account = array('link' => '<span id="myname"><i class="i
$lang->my->menu->index = '首页|my|index';
$lang->my->menu->todo = array('link' => '待办|my|todo|', 'subModule' => 'todo');
$lang->my->menu->task = array('link' => '任务|my|task|', 'subModule' => 'task');
$lang->my->menu->bug = array('link' => 'Bug|my|bug|', 'subModule' => 'bug');
$lang->my->menu->bug = array('link' => 'Bug|my|bug|', 'subModule' => 'bug');
$lang->my->menu->testtask = array('link' => '测试|my|testtask|', 'subModule' => 'testcase,testtask', 'alias' => 'testcase');
$lang->my->menu->story = array('link' => '需求|my|story|', 'subModule' => 'story');
$lang->my->menu->story = array('link' => '需求|my|story|', 'subModule' => 'story');
$lang->my->menu->myProject = "{$lang->projectCommon}|my|project|";
$lang->my->menu->dynamic = '动态|my|dynamic|';
$lang->my->menu->profile = array('link' => '档案|my|profile', 'alias' => 'editprofile');
$lang->my->menu->changePassword = '密码|my|changepassword';
$lang->my->menu->manageContacts = '联系人|my|managecontacts';
$lang->my->menu->score = array('link' => '积分|score|browse', 'subModule' => 'score');
$lang->todo = new stdclass();
$lang->todo = new stdclass();
$lang->todo->menu = $lang->my->menu;
$lang->score = new stdclass();
$lang->score->menu = $lang->my->menu;
/* 产品视图设置。*/
$lang->product = new stdclass();
$lang->product->menu = new stdclass();
@@ -342,7 +346,6 @@ $lang->admin->menu->cron = array('link' => '计划任务|cron|index', 'subM
$lang->admin->menu->trashes = array('link' => '回收站|action|trash', 'subModule' => 'action');
$lang->admin->menu->dev = array('link' => '二次开发|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
$lang->admin->menu->entry = array('link' => '接口|entry|browse', 'alias' => 'create,edit', 'subModule' => 'entry,webhook');
$lang->admin->menu->score = array('link' => '积分|score|browse', 'subModule' => 'score');
$lang->admin->menu->sso = '然之集成|admin|sso';
$lang->convert = new stdclass();
@@ -358,7 +361,6 @@ $lang->dev = new stdclass();
$lang->entry = new stdclass();
$lang->webhook = new stdclass();
$lang->search = new stdclass();
$lang->score = new stdclass();
$lang->convert->menu = $lang->admin->menu;
$lang->upgrade->menu = $lang->admin->menu;
@@ -370,7 +372,6 @@ $lang->custom->menu = $lang->admin->menu;
$lang->editor->menu = $lang->admin->menu;
$lang->mail->menu = $lang->admin->menu;
$lang->dev->menu = $lang->admin->menu;
$lang->score->menu = $lang->admin->menu;
$lang->entry->menu = $lang->admin->menu;
$lang->webhook->menu = $lang->admin->menu;
@@ -395,6 +396,7 @@ $lang->menugroup->testreport = 'qa';
$lang->menugroup->people = 'company';
$lang->menugroup->dept = 'company';
$lang->menugroup->todo = 'my';
$lang->menugroup->score = 'my';
$lang->menugroup->action = 'admin';
$lang->menugroup->backup = 'admin';
$lang->menugroup->cron = 'admin';
@@ -403,7 +405,6 @@ $lang->menugroup->custom = 'admin';
$lang->menugroup->editor = 'admin';
$lang->menugroup->mail = 'admin';
$lang->menugroup->dev = 'admin';
$lang->menugroup->score = 'admin';
$lang->menugroup->entry = 'admin';
$lang->menugroup->webhook = 'admin';
+5 -4
View File
@@ -175,10 +175,14 @@ $lang->my->menu->dynamic = '動態|my|dynamic|';
$lang->my->menu->profile = array('link' => '檔案|my|profile', 'alias' => 'editprofile');
$lang->my->menu->changePassword = '密碼|my|changepassword';
$lang->my->menu->manageContacts = '聯繫人|my|managecontacts';
$lang->my->menu->score = array('link' => '積分|score|browse', 'subModule' => 'score');
$lang->todo = new stdclass();
$lang->todo->menu = $lang->my->menu;
$lang->score = new stdclass();
$lang->scoret->menu = $lang->my->menu;
/* 產品視圖設置。*/
$lang->product = new stdclass();
$lang->product->menu = new stdclass();
@@ -341,7 +345,6 @@ $lang->admin->menu->safe = array('link' => '安全|admin|safe', 'alias' =>
$lang->admin->menu->cron = array('link' => '計劃任務|cron|index', 'subModule' => 'cron');
$lang->admin->menu->trashes = array('link' => '資源回收筒|action|trash', 'subModule' => 'action');
$lang->admin->menu->dev = array('link' => '二次開發|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
$lang->admin->menu->score = array('link' => '積分|score|browse', 'subModule' => 'score');
$lang->admin->menu->sso = '然之整合|admin|sso';
$lang->convert = new stdclass();
@@ -355,7 +358,6 @@ $lang->mail = new stdclass();
$lang->cron = new stdclass();
$lang->dev = new stdclass();
$lang->search = new stdclass();
$lang->score = new stdclass();
$lang->convert->menu = $lang->admin->menu;
$lang->upgrade->menu = $lang->admin->menu;
@@ -367,7 +369,6 @@ $lang->custom->menu = $lang->admin->menu;
$lang->editor->menu = $lang->admin->menu;
$lang->mail->menu = $lang->admin->menu;
$lang->dev->menu = $lang->admin->menu;
$lang->scoret->menu = $lang->admin->menu;
/* 菜單分組。*/
$lang->menugroup = new stdclass();
@@ -390,6 +391,7 @@ $lang->menugroup->testreport = 'qa';
$lang->menugroup->people = 'company';
$lang->menugroup->dept = 'company';
$lang->menugroup->todo = 'my';
$lang->menugroup->score = 'my';
$lang->menugroup->action = 'admin';
$lang->menugroup->backup = 'admin';
$lang->menugroup->cron = 'admin';
@@ -398,7 +400,6 @@ $lang->menugroup->custom = 'admin';
$lang->menugroup->editor = 'admin';
$lang->menugroup->mail = 'admin';
$lang->menugroup->dev = 'admin';
$lang->menugroup->score = 'admin';
/* 錯誤提示信息。*/
$lang->error = new stdclass();
+1 -1
View File
@@ -164,6 +164,7 @@ class commonModel extends model
if($module == 'tutorial') return true;
if($module == 'block') return true;
if($module == 'product' and $method == 'showerrornone') return true;
if($module == 'score' and $method == 'browse') return true;
}
return false;
}
@@ -1131,7 +1132,6 @@ class commonModel extends model
/* Check is the super admin or not. */
if(!empty($app->user->admin)) return true;
/* If not super admin, check the rights. */
$rights = $app->user->rights['rights'];
$acls = $app->user->rights['acls'];
@@ -49,6 +49,7 @@ $(function()
success:function(){if(reload) window.location.reload();},
url: '<?php echo $this->createLink('datatable', 'ajaxSave')?>'
});
$.get(createLink('score', 'ajax', "method=switchToDataTable"));
};
window.saveDatatableConfig = saveDatatableConfig;
});
+18 -17
View File
@@ -1,21 +1,22 @@
<?php
$lang->custom->common = 'Custom';
$lang->custom->index = 'Home';
$lang->custom->set = 'Customize';
$lang->custom->restore = 'Reset to Default';
$lang->custom->key = 'Key';
$lang->custom->value = 'Value';
$lang->custom->flow = 'Process';
$lang->custom->working = 'Working';
$lang->custom->select = 'Select Process';
$lang->custom->branch = 'Multi Branch';
$lang->custom->owner = 'Owner';
$lang->custom->module = 'Module';
$lang->custom->section = 'Section';
$lang->custom->lang = 'Language';
$lang->custom->setPublic = 'Set Public';
$lang->custom->required = 'Required';
$lang->custom->score = 'Score';
$lang->custom->common = 'Custom';
$lang->custom->index = 'Home';
$lang->custom->set = 'Customize';
$lang->custom->restore = 'Reset to Default';
$lang->custom->key = 'Key';
$lang->custom->value = 'Value';
$lang->custom->flow = 'Process';
$lang->custom->working = 'Working';
$lang->custom->select = 'Select Process';
$lang->custom->branch = 'Multi Branch';
$lang->custom->owner = 'Owner';
$lang->custom->module = 'Module';
$lang->custom->section = 'Section';
$lang->custom->lang = 'Language';
$lang->custom->setPublic = 'Set Public';
$lang->custom->required = 'Required';
$lang->custom->score = 'Score';
$lang->custom->scoreReset = 'Reset Score';
$lang->custom->object['story'] = 'Story';
$lang->custom->object['task'] = 'Task';
+18 -17
View File
@@ -1,21 +1,22 @@
<?php
$lang->custom->common = '自定义';
$lang->custom->index = '首页';
$lang->custom->set = '自定义配置';
$lang->custom->restore = '恢复默认';
$lang->custom->key = '键';
$lang->custom->value = '值';
$lang->custom->flow = '流程';
$lang->custom->working = '工作方式';
$lang->custom->select = '请选择流程:';
$lang->custom->branch = '多分支';
$lang->custom->owner = '所有者';
$lang->custom->module = '模块';
$lang->custom->section = '附加部分';
$lang->custom->lang = '所属语言';
$lang->custom->setPublic = '设为公共';
$lang->custom->required = '必填项';
$lang->custom->score = '积分';
$lang->custom->common = '自定义';
$lang->custom->index = '首页';
$lang->custom->set = '自定义配置';
$lang->custom->restore = '恢复默认';
$lang->custom->key = '键';
$lang->custom->value = '值';
$lang->custom->flow = '流程';
$lang->custom->working = '工作方式';
$lang->custom->select = '请选择流程:';
$lang->custom->branch = '多分支';
$lang->custom->owner = '所有者';
$lang->custom->module = '模块';
$lang->custom->section = '附加部分';
$lang->custom->lang = '所属语言';
$lang->custom->setPublic = '设为公共';
$lang->custom->required = '必填项';
$lang->custom->score = '积分';
$lang->custom->scoreReset = '重置积分';
$lang->custom->object['story'] = '需求';
$lang->custom->object['task'] = '任务';
+16 -15
View File
@@ -1,19 +1,20 @@
<?php
$lang->custom->common = '自定義';
$lang->custom->index = '首頁';
$lang->custom->set = '自定義配置';
$lang->custom->restore = '恢復預設';
$lang->custom->key = '鍵';
$lang->custom->value = '值';
$lang->custom->flow = '流程';
$lang->custom->working = '工作方式';
$lang->custom->select = '請選擇流程:';
$lang->custom->branch = '多分支';
$lang->custom->owner = '所有者';
$lang->custom->module = '模組';
$lang->custom->section = '附加部分';
$lang->custom->lang = '所屬語言';
$lang->custom->score = '積分';
$lang->custom->common = '自定義';
$lang->custom->index = '首頁';
$lang->custom->set = '自定義配置';
$lang->custom->restore = '恢復預設';
$lang->custom->key = '鍵';
$lang->custom->value = '值';
$lang->custom->flow = '流程';
$lang->custom->working = '工作方式';
$lang->custom->select = '請選擇流程:';
$lang->custom->branch = '多分支';
$lang->custom->owner = '所有者';
$lang->custom->module = '模組';
$lang->custom->section = '附加部分';
$lang->custom->lang = '所屬語言';
$lang->custom->score = '積分';
$lang->custom->scoreReset = '重置積分';
$lang->custom->object['story'] = '需求';
$lang->custom->object['task'] = '任務';
+2 -2
View File
@@ -282,12 +282,11 @@ class customModel extends model
$allMenu = $module == 'main' ? $lang->menu : (isset($lang->$module->menu) ? $lang->$module->menu : $lang->my->menu);
if($module == 'product' and isset($allMenu->branch)) $allMenu->branch = str_replace('@branch@', $lang->custom->branch, $allMenu->branch);
if($module != 'main' and isset($lang->menugroup->$module)) $module = $lang->menugroup->$module;
if($module == 'admin' and empty($config->global->score)) unset($allMenu->score);
$flowModule = $config->global->flow . '_' . $module;
$customMenu = isset($config->customMenu->$flowModule) ? $config->customMenu->$flowModule : array();
if(commonModel::isTutorialMode() && $module === 'main')$customMenu = 'my,product,project,qa,company';
if(!empty($customMenu) && is_string($customMenu) && substr($customMenu, 0, 1) === '[') $customMenu = json_decode($customMenu);
if($module == 'my' && empty($config->global->score)) unset($allMenu->score);
$menu = self::setMenuByConfig($allMenu, $customMenu, $module);
return $menu;
}
@@ -373,6 +372,7 @@ class customModel extends model
}
$this->loadModel('setting')->setItem($settingKey, $menu);
$this->loadModel('score')->score('ajax', 'customMenu');
}
/**
+1 -1
View File
@@ -19,7 +19,7 @@
</tr>
<tr>
<td></td>
<td><?php echo html::submitButton() ?></td>
<td><?php echo html::submitButton() ?> <?php echo html::a(inLink('resetScore'), "<i class='icon-refresh'></i> " . $lang->custom->scoreReset, '', "class='btn'");?></td>
</tr>
</table>
</form>
+1
View File
@@ -431,6 +431,7 @@ class docModel extends model
$docContent->doc = $docID;
$docContent->files = join(',', array_keys($files));
$this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
$this->loadModel('score')->score('doc', 'create', $docID);
return array('status' => 'new', 'id' => $docID);
}
return false;
+3
View File
@@ -7,6 +7,9 @@ $config->product->customBatchEditFields = 'PO,QD,RD,status,type,desc';
$config->product->custom = new stdclass();
$config->product->custom->batchEditFields = 'PO,QD,RD,status';
$config->product->list = new stdclass();
$config->product->list->exportFields = 'id,name,activeStories,changedStories,draftStories,closedStories,plans,releases,bugs,unResolvedBugs,assignToNullBugs';
global $lang, $app;
$app->loadLang('story');
$config->product->search['module'] = 'story';
+49
View File
@@ -660,6 +660,55 @@ class product extends control
$this->display();
}
/**
* Export product.
*
* @param string $status
* @param string $orderBy
* @access public
* @return void
*/
public function export($status, $orderBy)
{
if($_POST)
{
$productLang = $this->lang->product;
$productConfig = $this->config->product;
/* Create field lists. */
$fields = $this->post->exportFields ? $this->post->exportFields : explode(',', $productConfig->list->exportFields);
foreach($fields as $key => $fieldName)
{
$fieldName = trim($fieldName);
$fields[$fieldName] = zget($productLang, $fieldName);
unset($fields[$key]);
}
$productStats = $this->product->getStats($orderBy, null, $status);
foreach($productStats as $i => $product)
{
$product->activeStories = (int)$product->stories['active'];
$product->changedStories = (int)$product->stories['changed'];
$product->draftStories = (int)$product->stories['draft'];
$product->closedStories = (int)$product->stories['closed'];
$product->unResolvedBugs = (int)$product->unResolved;
$product->assignToNullBugs = (int)$product->assignToNull;
if($this->post->exportType == 'selected')
{
$checkedItem = $this->cookie->checkedItem;
if(strpos(",$checkedItem,", ",{$product->id},") === false) unset($productStats[$i]);
}
}
$this->post->set('fields', $fields);
$this->post->set('rows', $productStats);
$this->post->set('kind', 'product');
$this->fetch('file', 'export2' . $this->post->fileType, $_POST);
}
$this->display();
}
/**
* Doc for compatible.
*
+8
View File
@@ -26,6 +26,7 @@ $lang->product->other = 'Other:';
$lang->product->closed = 'Closed';
$lang->product->updateOrder = 'Ranking';
$lang->product->all = "All {$lang->productCommon}";
$lang->product->export = "Export";
$lang->product->basicInfo = 'Basic Info';
$lang->product->otherInfo = 'Other Info';
@@ -42,6 +43,13 @@ $lang->product->doc = 'Documents';
$lang->product->project = $lang->projectCommon . 'List';
$lang->product->build = 'Build List';
$lang->product->activeStories = 'Activated Story';
$lang->product->changedStories = 'Changed Story';
$lang->product->draftStories = 'Draft Story';
$lang->product->closedStories = 'Closed Story';
$lang->product->unResolvedBugs = 'Unresolved Bug';
$lang->product->assignToNullBugs = 'No Assigned Bug';
$lang->product->confirmDelete = " Do you want to delete {$lang->productCommon}?";
$lang->product->errorNoProduct = "{$lang->productCommon} is not created yet!";
+9
View File
@@ -26,6 +26,7 @@ $lang->product->other = '其他:';
$lang->product->closed = '已关闭';
$lang->product->updateOrder = "排序";
$lang->product->all = "所有{$lang->productCommon}";
$lang->product->export = "导出";
$lang->product->basicInfo = '基本信息';
$lang->product->otherInfo = '其他信息';
@@ -42,11 +43,19 @@ $lang->product->doc = '文档列表';
$lang->product->project = $lang->projectCommon . '列表';
$lang->product->build = '版本列表';
$lang->product->activeStories = '激活需求';
$lang->product->changedStories = '已变更需求';
$lang->product->draftStories = '草稿需求';
$lang->product->closedStories = '已关闭需求';
$lang->product->unResolvedBugs = '未解决Bug';
$lang->product->assignToNullBugs = '未指派Bug';
$lang->product->confirmDelete = " 您确定删除该{$lang->productCommon}吗?";
$lang->product->errorNoProduct = "还没有创建{$lang->productCommon}!";
$lang->product->accessDenied = "您无权访问该{$lang->productCommon}";
$lang->product->id = "编号";
$lang->product->name = "{$lang->productCommon}名称";
$lang->product->code = "{$lang->productCommon}代号";
$lang->product->order = '排序';
+10 -6
View File
@@ -13,6 +13,10 @@
<?php include '../../common/view/sortable.html.php';?>
<div id='featurebar'>
<div class='actions'>
<?php
$link = $this->createLink('product', 'export', "status=$status&orderBy=$orderBy");
if(common::hasPriv('product', 'export'))echo html::a($link, "<i class='icon-download-alt icon'></i> " . $lang->export, '', "class='export btn'");
?>
<?php echo html::a($this->createLink('product', 'create'), "<i class='icon-plus'></i> " . $lang->product->create,'', "class='btn'") ?>
</div>
<ul class='nav'>
@@ -42,15 +46,15 @@
<tr>
<th class='w-id'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->product->name);?></th>
<th class='w-80px'><?php echo $lang->story->statusList['active'] . $lang->story->common;?></th>
<th class='w-80px'><?php echo $lang->story->statusList['changed'] . $lang->story->common;?></th>
<th class='w-80px'><?php echo $lang->story->statusList['draft'] . $lang->story->common;?></th>
<th class='w-80px'><?php echo $lang->story->statusList['closed'] . $lang->story->common;?></th>
<th class='w-80px'><?php echo $lang->product->activeStories;?></th>
<th class='w-80px'><?php echo $lang->product->changedStories;?></th>
<th class='w-80px'><?php echo $lang->product->draftStories;?></th>
<th class='w-80px'><?php echo $lang->product->closedStories;?></th>
<th class='w-80px'><?php echo $lang->product->plans;?></th>
<th class='w-80px'><?php echo $lang->product->releases;?></th>
<th class='w-80px'><?php echo $lang->product->bugs;?></th>
<th class='w-80px'><?php echo $lang->bug->unResolved;?></th>
<th class='w-80px'><?php echo $lang->bug->assignToNull;?></th>
<th class='w-80px'><?php echo $lang->product->unResolvedBugs;?></th>
<th class='w-80px'><?php echo $lang->product->assignToNullBugs;?></th>
<?php if($canOrder):?>
<th class='w-60px sort-default'><?php common::printOrderLink('order', $orderBy, $vars, $lang->product->updateOrder);?></th>
<?php endif;?>
+13
View File
@@ -0,0 +1,13 @@
<?php
/**
* The export view file of product module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package product
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../file/view/export.html.php';?>
+1
View File
@@ -151,6 +151,7 @@ class productplanModel extends model
{
$planID = $this->dao->lastInsertID();
$this->file->updateObjectID($this->post->uid, $planID, 'plan');
$this->loadModel('score')->score('productplan', 'create', $planID);
return $planID;
}
}
+3
View File
@@ -5,6 +5,9 @@ $config->project->orderBy = 'isDone,status,order_desc';
$config->project->maxBurnDay = '31';
$config->project->weekend = '2';
$config->project->list = new stdclass();
$config->project->list->exportFields = 'id,name,code,PM,end,status,totalEstimate,totalConsumed,totalLeft,progess';
global $lang, $app;
$app->loadLang('task');
$config->project->create = new stdclass();
+52
View File
@@ -2032,6 +2032,58 @@ class project extends control
$this->display();
}
/**
* Export project.
*
* @param string $status
* @param int $productID
* @param string $orderBy
* @access public
* @return void
*/
public function export($status, $productID, $orderBy)
{
if($_POST)
{
$projectLang = $this->lang->project;
$projectConfig = $this->config->project;
/* Create field lists. */
$fields = $this->post->exportFields ? $this->post->exportFields : explode(',', $projectConfig->list->exportFields);
foreach($fields as $key => $fieldName)
{
$fieldName = trim($fieldName);
$fields[$fieldName] = zget($projectLang, $fieldName);
unset($fields[$key]);
}
$projectStats = $this->project->getProjectStats($status == 'byproduct' ? 'all' : $status, $productID, 0, 30, $orderBy, null);
$users = $this->loadModel('user')->getPairs('noletter');
foreach($projectStats as $i => $project)
{
$project->PM = zget($users, $project->PM);
$project->status = isset($project->delay) ? $projectLang->delayed : $projectLang->statusList[$project->status];
$project->totalEstimate = $project->hours->totalEstimate;
$project->totalConsumed = $project->hours->totalConsumed;
$project->totalLeft = $project->hours->totalLeft;
$project->progress = $project->hours->progress . '%';
if($this->post->exportType == 'selected')
{
$checkedItem = $this->cookie->checkedItem;
if(strpos(",$checkedItem,", ",{$project->id},") === false) unset($projectStats[$i]);
}
}
$this->post->set('fields', $fields);
$this->post->set('rows', $projectStats);
$this->post->set('kind', 'project');
$this->fetch('file', 'export2' . $this->post->fileType, $_POST);
}
$this->display();
}
/**
* Doc for compatible.
*
+1
View File
@@ -58,6 +58,7 @@ $lang->project->activate = 'Activate';
$lang->project->putoff = 'Deplay';
$lang->project->suspend = 'Suspend';
$lang->project->close = 'Close';
$lang->project->export = 'Export';
$lang->project->typeList['sprint'] = 'Sprint';
$lang->project->typeList['waterfall'] = 'Waterfall';
+1
View File
@@ -58,6 +58,7 @@ $lang->project->activate = '激活';
$lang->project->putoff = '延期';
$lang->project->suspend = '挂起';
$lang->project->close = '关闭';
$lang->project->export = '导出';
$lang->project->typeList['sprint'] = "短期$lang->projectCommon";
$lang->project->typeList['waterfall'] = "长期$lang->projectCommon";
+2 -2
View File
@@ -291,7 +291,7 @@ class projectModel extends model
$lib->main = '1';
$lib->acl = $project->acl == 'open' ? 'open' : 'private';
$this->dao->insert(TABLE_DOCLIB)->data($lib)->exec();
$this->loadModel('score')->score('project', 'create', $projectID);
return $projectID;
}
}
@@ -537,7 +537,7 @@ class projectModel extends model
->autoCheck()
->where('id')->eq((int)$projectID)
->exec();
$this->loadModel('score')->score('project', 'close', $oldProject);
if(!dao::isError()) return common::createChanges($oldProject, $project);
}
+1
View File
@@ -14,6 +14,7 @@
<?php include '../../common/view/sortable.html.php';?>
<div id='featurebar'>
<div class='actions'>
<?php common::printLink('project', 'export', "status=$status&productID=$productID&orderBy=$orderBy", "<i class='icon-download-alt'></i> " . $lang->export, '', "class='btn export'")?>
<?php common::printLink('project', 'create', '', "<i class='icon-plus'></i> " . $lang->project->create, '', "class='btn'")?>
</div>
<ul class='nav'>
+13
View File
@@ -0,0 +1,13 @@
<?php
/**
* The export view file of project module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package project
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../file/view/export.html.php';?>
+1
View File
@@ -145,6 +145,7 @@ class releaseModel extends model
$releaseID = $this->dao->lastInsertID();
$this->file->updateObjectID($this->post->uid, $releaseID, 'release');
$this->file->saveUpload('release', $releaseID);
$this->loadModel('score')->score('release', 'create', $releaseID);
if(!dao::isError()) return $releaseID;
}
+2
View File
@@ -210,6 +210,8 @@ class report extends control
/* Get email content and title.*/
$this->view->mail = $mail;
$this->view->mailTitle = $mailTitle;
$oldViewType = $this->viewType;
if($oldViewType == 'json') $this->viewType = 'html';
$mailContent = $this->parse('report', 'dailyreminder');
+54
View File
@@ -1 +1,55 @@
<?php
$config->score = new stdClass();
$config->score->model['user']['login'] = array('num' => 3, 'time' => 24, 'score' => 1, 'other' => '');
$config->score->model['user']['changePassword'] = array('num' => 1, 'time' => 0, 'score' => 10, 'other' => array(1 => 2, 2 => 5));
$config->score->model['user']['editProfile'] = array('num' => 1, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['tutorial']['keepAll'] = array('num' => 1, 'time' => 0, 'score' => 100, 'other' => '');
$config->score->model['ajax']['selectTheme'] = array('num' => 1, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['ajax']['selectLang'] = array('num' => 1, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['ajax']['showSearchMenu'] = array('num' => 1, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['ajax']['dragSelected'] = array('num' => 1, 'time' => 0, 'score' => 20, 'other' => '');
$config->score->model['ajax']['lastNext'] = array('num' => 1, 'time' => 0, 'score' => 20, 'other' => '');
$config->score->model['ajax']['switchToDataTable'] = array('num' => 1, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['ajax']['submitPage'] = array('num' => 1, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['ajax']['customMenu'] = array('num' => 1, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['ajax']['quickDump'] = array('num' => 1, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['ajax']['batchCreate'] = array('num' => 1, 'time' => 0, 'score' => 20, 'other' => '');
$config->score->model['ajax']['batchEdit'] = array('num' => 1, 'time' => 0, 'score' => 20, 'other' => '');
$config->score->model['doc']['create'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['todo']['create'] = array('num' => 5, 'time' => 24, 'score' => 1, 'other' => '');
$config->score->model['story']['create'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['story']['close'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => array('createID' => 2));//每个需求被完成关闭,需求的创建者额外增加2分,关闭者增加1分
$config->score->model['task']['create'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['task']['close'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['task']['finish'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => array(1 => 2, 2 => 1, 3 => 0));
$config->score->model['bug']['create'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['bug']['confirmBug'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => array(1 => 3, 2 => 2, 3 => 1));
$config->score->model['bug']['createFormCase'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['bug']['resolve'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => array(1 => 3, 2 => 2, 3 => 1));
$config->score->model['bug']['saveTplModal'] = array('num' => 0, 'time' => 0, 'score' => 20, 'other' => '');
$config->score->model['testTask']['runCase'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['testcase']['create'] = array('num' => 0, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['build']['create'] = array('num' => 0, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['project']['create'] = array('num' => 0, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['project']['close'] = array('num' => 0, 'time' => 0, 'score' => 0, 'other' => array('manager' => array(20, 10), 'member' => array(5, 5)));
$config->score->model['productplan']['create'] = array('num' => 0, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['release']['create'] = array('num' => 0, 'time' => 0, 'score' => 10, 'other' => '');
$config->score->model['block']['set'] = array('num' => 1, 'time' => 0, 'score' => 20, 'other' => '');
$config->score->model['search']['saveQuery'] = array('num' => 1, 'time' => 0, 'score' => 1, 'other' => '');
$config->score->model['search']['saveQueryAdvanced'] = array('num' => 1, 'time' => 0, 'score' => 1, 'other' => '');
+36 -4
View File
@@ -1,7 +1,6 @@
<?php
/**
* The control file of score module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @author Memory <lvtao@cnezsoft.com>
* @package score
@@ -11,20 +10,53 @@
class score extends control
{
/**
* score list
* score constructor.
*
* @param string $module
* @param string $method
*
* @access public
* @return mixed
*/
public function browse($recTotal = 0, $recPerPage = 100)
public function __construct($module = '', $method = '')
{
parent::__construct($module, $method);
$this->loadModel('my')->setMenu();
}
/**
* Get score list
*
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
*
* @access public
* @return mixed
*/
public function browse($recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage);
$pager = new pager($recTotal, $recPerPage, $pageID);
$scores = $this->score->getScores($pager);
$this->view->title = $this->lang->score->common;
$this->view->user = $this->loadModel('user')->getById($this->app->user->account);
$this->view->pager = $pager;
$this->view->scores = $scores;
$this->display();
}
/**
* Ajax action score
*
* @param string $method $.get(createLink('score', 'ajax', "method=selectLang"));
*
* @access public
* @return void
*/
public function ajax($method = '')
{
$this->loadModel('score')->score('ajax', $method);
}
}
+61 -8
View File
@@ -1,17 +1,70 @@
<?php
$lang->score->common = '积分';
$lang->score->record = '积分记录';
$lang->score->reset = '重置积分';
$lang->score->common = '积分';
$lang->score->record = '积分记录';
$lang->score->current = '当前积分';
$lang->score->level = '等级积分';
$lang->score->id = '编号';
$lang->score->userID = '用户ID';
$lang->score->account = '用户';
$lang->score->model = '模块';
$lang->score->method = '方式';
$lang->score->type = '类型';
$lang->score->method = '动作';
$lang->score->before = '之前';
$lang->score->score = '分值';
$lang->score->after = '之后';
$lang->score->time = '时间';
$lang->score->desc = '描述';
$lang->score->methods['login'] = '登录';
$lang->score->methods['admin'] = '';
$lang->score->methods['tutorial'] = '新手教程';
$lang->score->models['task'] = '任务';
$lang->score->models['tutorial'] = '新手教程';
$lang->score->models['user'] = '用户';
$lang->score->models['ajax'] = '';
$lang->score->models['doc'] = '文档';
$lang->score->models['todo'] = '待办';
$lang->score->models['story'] = '需求';
$lang->score->models['bug'] = 'Bug';
$lang->score->models['testTask'] = '用例';
$lang->score->models['build'] = 'Build';
$lang->score->models['project'] = '项目';
$lang->score->models['productplan'] = '计划';
$lang->score->models['release'] = '发布';
$lang->score->models['block'] = '区块';
$lang->score->models['search'] = '搜索';
$lang->score->methods['task']['create'] = '创建任务';
$lang->score->methods['task']['close'] = '关闭任务';
$lang->score->methods['task']['finish'] = '完成任务';
$lang->score->methods['tutorial']['keepAll'] = '学习完成';
$lang->score->methods['user']['login'] = '登录';
$lang->score->methods['user']['changePassword'] = '修改密码';
$lang->score->methods['user']['editProfile'] = '修改个人资料';
$lang->score->methods['ajax']['selectTheme'] = '切换主题';
$lang->score->methods['ajax']['selectLang'] = '切换语言';
$lang->score->methods['ajax']['showSearchMenu'] = '搜索高级用法';
$lang->score->methods['ajax']['customMenu'] = '自定义菜单';
$lang->score->methods['ajax']['dragSelected'] = '列表页面拖动选中';
$lang->score->methods['ajax']['lastNext'] = '快捷键翻页';
$lang->score->methods['ajax']['switchToDataTable'] = '使用高级表格';
$lang->score->methods['ajax']['submitPage'] = '修改分页数量';
$lang->score->methods['ajax']['quickDump'] = '使用快速跳转';
$lang->score->methods['ajax']['batchCreate'] = '首次使用批量添加';
$lang->score->methods['ajax']['batchEdit'] = '首次使用批量编辑';
$lang->score->methods['doc']['create'] = '创建文档';
$lang->score->methods['todo']['create'] = '创建待办';
$lang->score->methods['story']['create'] = '创建需求';
$lang->score->methods['story']['close'] = '需求关闭';
$lang->score->methods['bug']['create'] = '创建Bug';
$lang->score->methods['bug']['confirmBug'] = '确认Bug';
$lang->score->methods['bug']['createFormCase'] = '从用例创建';
$lang->score->methods['bug']['resolve'] = '解决Bug';
$lang->score->methods['bug']['saveTplModal'] = '保存模板';
$lang->score->methods['testTask']['runCase'] = '执行用例';
$lang->score->methods['build']['create'] = '创建版本';
$lang->score->methods['project']['create'] = '创建项目';
$lang->score->methods['project']['close'] = '项目完成';
$lang->score->methods['productplan']['create'] = '创建计划';
$lang->score->methods['release']['create'] = '创建发布';
$lang->score->methods['block']['set'] = '区块自定义设置';
$lang->score->methods['search']['saveQuery'] = '保存搜索条件';
$lang->score->methods['search']['saveQueryAdvanced'] = '使用高级搜索';
+196 -2
View File
@@ -1,7 +1,6 @@
<?php
/**
* The model file of score module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @author Memory <lvtao@cnezsoft.com>
* @package score
@@ -10,9 +9,204 @@
*/
class scoreModel extends model
{
/**
* get user score logs
*
* @param $pager
*
* @access public
* @return array|bool
*/
public function getScores($pager)
{
$scores = $this->dao->select('*')->from(TABLE_SCORE)->where('account')->eq($this->app->user->account)->orderBy('time_desc,id_desc')->page($pager)->fetchAll();
return empty($scores) ? array() : $scores;
}
/**
* add score logs
*
* @param string $model
* @param string $method
* @param string $param
*
* @access public
* @return bool
*/
public function score($model = '', $method = '', $param = '')
{
if(empty($this->config->score->model[$model][$method])) return true;
$rule = $this->config->score->model[$model][$method];
$desc = $this->lang->score->models[$model];
$user = $this->app->user->account;
switch($model)
{
case 'user':
if($method == 'login') $desc = $this->lang->score->methods[$model][$method] . 'IP:' . helper::getRemoteIp();
if($method == 'changePassword')
{
if(!empty($rule['other'][$param])) $rule['score'] = $rule['score'] + $rule['other'][$param];
$desc = $this->lang->score->methods[$model][$method];
}
break;
case 'doc':
if($method == 'create') $desc .= 'ID:' . $param;
break;
case 'todo':
if($method == 'create') $desc .= 'ID:' . $param;
break;
case 'story':
$desc .= 'ID:' . $param;
if($method == 'close')
{
$createUser = $this->dao->findById($param)->from(TABLE_STORY)->fetch();
if(!empty($createUser))
{
$newRule = $rule;
$newRule['score'] = $rule['other']['createID'];
$this->saveScore($createUser->openedBy, $newRule, $model, $method, $desc);
unset($newRule);
}
}
break;
case 'task':
$desc .= 'ID:' . $param;
if($method == 'finish')
{
$desc = $this->lang->score->methods[$model][$method] . 'ID:' . $param;
//每完成一个任务,增加初始积分1 + 工时积分round(工时 /10 * 预计 / 消耗) + 优先级积分(p1 2, p2, 1) 如果任务取消了,没有积分。
$task = $this->loadModel('task')->getById($param);
if(!empty($rule['other'][$task->pri])) $rule['score'] = $rule['score'] + $rule['other'][$task->pri];
if(!empty($task->estimate)) $rule['score'] = $rule['score'] + round(($task->consumed / 10 * $task->estimate / $task->consumed), 1);
}
break;
case 'bug':
$desc .= 'ID:' . $param;
if($method == 'createFormCase')
{
$desc = $this->lang->score->models['testcase'] . 'ID:' . $param;
$caseUser = $this->dao->findById($param)->from(TABLE_CASE)->fetch();
if(!empty($caseUser))
{
$user = $caseUser->openedBy;
}
}
if($method == 'saveTplModal') $desc = $this->lang->score->methods[$model][$method] . 'ID:' . $param;
if($method == 'confirmBug')
{
$user = $param->openedBy;
if(!empty($rule['other'][$param->severity])) $rule['score'] = $rule['score'] + $rule['other'][$param->severity];
}
if($method == 'resolve' && !empty($rule['other'][$param->severity])) $rule['score'] = $rule['score'] + $rule['other'][$param->severity];
break;
case 'testTask':
if($method == 'runCase') $desc = $this->lang->score->methods[$model][$method] . 'ID:' . $param;
break;
case 'build':
if($method == 'create') $desc .= 'ID:' . $param;
break;
case 'project':
if($method == 'create') $desc .= 'ID:' . $param;
if($method == 'close')
{
$desc = $this->lang->score->methods[$model][$method] . ',' . $desc . 'ID:' . $param->id;
if(!empty($param->PM))
{
$rule['score'] = $param->end > date('Y-m-d') ? $rule['other']['manager'][0] + $rule['other']['manager'][1] : $rule['other']['manager'][0];
$this->saveScore($param->PM, $rule, $model, $method, $desc);
}
$teams = $this->dao->select('account')->from(TABLE_TEAM)->where('project')->eq($param->id)->fetchGroup('account');
if(!empty($teams))
{
$users = array_keys($teams);
$rule['score'] = $param->end > date('Y-m-d') ? $rule['other']['member'][0] + $rule['other']['member'][1] : $rule['other']['member'][0];
foreach($users as $user)
{
if($user != $param->PM) $this->saveScore($user, $rule, $model, $method, $desc);
}
}
}
return true;
break;
case 'productplan':
if($method == 'create') $desc .= 'ID:' . $param;
break;
case 'release':
if($method == 'create') $desc .= 'ID:' . $param;
break;
case 'testcase':
if($method == 'create') $desc .= 'ID:' . $param;
break;
case 'search':
if($method == 'saveQuery') $desc .= 'ID:' . $param;
if($method == 'saveQueryAdvanced') $desc = $this->lang->score->methods[$model][$method];
break;
case 'ajax':
$desc = $this->lang->score->methods[$model][$method];
break;
}
$this->saveScore($user, $rule, $model, $method, $desc);
}
/**
* save user score
*
* @param string $account
* @param array $rule
* @param string $model
* @param string $method
* @param string $desc
*
* @access private
* @return bool
*/
private function saveScore($account = '', $rule = array(), $model = '', $method = '', $desc = '')
{
if(!empty($rule['num']) || !empty($rule['time']))
{
if(empty($rule['time']))
{
$count = $this->dao->select('id')->from(TABLE_SCORE)->where('account')->eq($account)->andWhere('model')->eq($model)->andWhere('method')->eq($method)->count();
if($count >= $rule['num']) return true;
}
else
{
$count = $this->dao->select('id')->from(TABLE_SCORE)->where('account')->eq($account)->andWhere('time')->between(date('Y-m-d 0:0:0'), date('Y-m-d 23:59:59'))->andWhere('model')->eq($model)->andWhere('method')->eq($method)->count();
if($count >= $rule['num']) return true;
}
}
$this->dao->begin();
try
{
$user = $this->loadModel('user')->getById($account);
$data = new stdClass();
$data->account = $account;
$data->model = $model;
$data->method = $method;
$data->desc = $desc;
$data->before = $user->score;
$data->score = $rule['score'];
$data->after = $user->score + $rule['score'];
$data->time = helper::now();
$this->dao->insert(TABLE_SCORE)->data($data)->exec();
$this->dao->query("UPDATE " . TABLE_USER . " SET `score`=`score` + " . $rule['score'] . ",`score_level`=`score_level` + " . $rule['score'] . " WHERE `account`='" . $account . "'");
$this->dao->commit();
}
catch(ErrorException $e)
{
$this->dao->rollBack();
}
}
/**
* reset all user score and level score
* @access public
* @return void
*/
public function resetScore()
{
}
}
+30 -24
View File
@@ -1,7 +1,6 @@
<?php
/**
* The browse view file of score module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Memory <lvtao@cnezsoft.com>
@@ -10,38 +9,45 @@
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id='titlebar'>
<div class='heading'><?php echo html::icon($lang->icons['score']);?> <?php echo $lang->score->record;?></div>
<?php include '../../common/view/header.html.php'; ?>
<div id='titlebar'>
<div class='heading'><?php echo html::icon($lang->icons['score']); ?><?php echo $lang->score->record; ?></div>
<div class='actions'>
<?php echo html::a(inLink('reset'), "<i class='icon-refresh'></i> " . $lang->score->reset, '', "class='btn'");?>
<span class='btn disabled'><label><?php echo $lang->score->current; ?>:</label><?php echo $user->score; ?></span>
<span class='btn disabled hidden'><label><?php echo $lang->score->level; ?>:</label><?php echo $user->score_level; ?></span>
</div>
</div>
<table class='table tablesorter'>
</div>
<table class='table tablesorter'>
<thead>
<tr class='colhead'>
<th><?php echo $lang->score->id;?></th>
<th><?php echo $lang->score->account;?></th>
<th><?php echo $lang->score->model;?></th>
<th><?php echo $lang->score->method;?></th>
<th><?php echo $lang->score->type;?></th>
<th><?php echo $lang->score->score;?></th>
<th><?php echo $lang->score->time;?></th>
<th class="w-200px"><?php echo $lang->score->time; ?></th>
<th class="w-150px"><?php echo $lang->score->model; ?></th>
<th class="w-150px"><?php echo $lang->score->method; ?></th>
<th class="w-100px"><?php echo $lang->score->before; ?></th>
<th class="w-100px"><?php echo $lang->score->score; ?></th>
<th class="w-100px"><?php echo $lang->score->after; ?></th>
<th><?php echo $lang->score->desc; ?></th>
</tr>
</thead>
<tbody>
<?php if(!empty($scores))foreach($scores as $score):?>
<tr class='text-center'>
</tr>
<?php endforeach;?>
<?php if(!empty($scores)) foreach($scores as $score): ?>
<tr class='text-center'>
<td><?php echo $score->time; ?></td>
<td><?php echo $lang->score->models[$score->model]; ?></td>
<td><?php echo $lang->score->methods[$score->model][$score->method]; ?></td>
<td><?php echo $score->before; ?></td>
<td><?php echo $score->score; ?></td>
<td><?php echo $score->after; ?></td>
<td><?php echo $score->desc; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr>
<td colspan='7'>
<?php $pager->show();?>
</td>
<td colspan='7'>
<?php $pager->show(); ?>
</td>
</tr>
</tfoot>
</table>
<?php include '../../common/view/footer.html.php';?>
</table>
<?php include '../../common/view/footer.html.php'; ?>
+5 -1
View File
@@ -47,7 +47,7 @@ class searchModel extends model
$groupItems = $this->config->search->groupItems;
$groupAndOr = strtoupper($this->post->groupAndOr);
if($groupAndOr != 'AND' and $groupAndOr != 'OR') $groupAndOr = 'AND';
$scoreNum = 0;
for($i = 1; $i <= $groupItems * 2; $i ++)
{
/* The and or between two groups. */
@@ -66,6 +66,8 @@ class searchModel extends model
if($this->post->$valueName == 'null') $this->post->$valueName = ''; // Null is special, stands to empty.
if($this->post->$valueName == 'ZERO') $this->post->$valueName = 0; // ZERO is special, stands to 0.
$scoreNum += 1;
/* Set and or. */
$andOr = strtoupper($this->post->$andOrName);
if($andOr != 'AND' and $andOr != 'OR') $andOr = 'AND';
@@ -127,6 +129,7 @@ class searchModel extends model
$formSessionName = $this->post->module . 'Form';
$this->session->set($querySessionName, $where);
$this->session->set($formSessionName, $_POST);
if($scoreNum > 2) $this->loadModel('score')->score('search', 'saveQueryAdvanced');
}
/**
@@ -303,6 +306,7 @@ class searchModel extends model
$featureBarConfig->value = json_encode($newConfig);
$this->dao->replace(TABLE_CONFIG)->data($featureBarConfig)->exec();
}
$this->loadModel('score')->score('search', 'saveQuery', $queryID);
return $queryID;
}
return false;
+6 -2
View File
@@ -228,6 +228,7 @@ class storyModel extends model
}
}
$this->setStage($storyID);
$this->loadModel('score')->score('story', 'create',$storyID);
return array('status' => 'created', 'id' => $storyID);
}
return false;
@@ -342,6 +343,7 @@ class storyModel extends model
$this->dao->insert(TABLE_STORYSPEC)->data($specData)->exec();
$actionID = $this->action->create('story', $storyID, 'Opened', '');
$this->loadModel('score')->score('story', 'create',$storyID);
$mails[$i] = new stdclass();
$mails[$i]->storyID = $storyID;
$mails[$i]->actionID = $actionID;
@@ -357,7 +359,7 @@ class storyModel extends model
if(is_dir($realPath)) $classFile->removeDir($realPath);
unset($_SESSION['storyImagesFile']);
}
$this->loadModel('score')->score('ajax', 'batchCreate');
return $mails;
}
@@ -607,7 +609,7 @@ class storyModel extends model
}
}
}
$this->loadModel('score')->score('ajax', 'batchEdit');
return $allChanges;
}
@@ -783,6 +785,7 @@ class storyModel extends model
->batchCheck($this->config->story->close->requiredFields, 'notempty')
->checkIF($story->closedReason == 'duplicate', 'duplicateStory', 'notempty')
->where('id')->eq($storyID)->exec();
if($this->post->closedReason == 'done') $this->loadModel('score')->score('story', 'close', $storyID);
return common::createChanges($oldStory, $story);
}
@@ -846,6 +849,7 @@ class storyModel extends model
{
die(js::error('story#' . $storyID . dao::getError(true)));
}
if($story->stage == 'released') $this->loadModel('score')->score('story', 'close', $storyID);
}
return $allChanges;
+6 -6
View File
@@ -40,8 +40,6 @@ class taskModel extends model
->remove('after,files,labels,assignedTo,uid,storyEstimate,storyDesc,storyPri,team,teamEstimate,teamMember,multiple,teams')
->get();
foreach($this->post->assignedTo as $assignedTo)
{
/* When type is affair and has assigned then ignore none. */
@@ -126,7 +124,7 @@ class taskModel extends model
$team->task = $taskID;
$this->dao->insert(TABLE_TEAM)->data($team)->autoCheck()->exec();
}
$this->loadModel('score')->score('task', 'create', $taskID);
$tasksID[$assignedTo] = array('status' => 'created', 'id' => $taskID);
}
return $tasksID;
@@ -226,13 +224,14 @@ class taskModel extends model
$taskID = $this->dao->lastInsertID();
if($story) $this->story->setStage($tasks->story[$i]);
$actionID = $this->action->create('task', $taskID, 'Opened', '');
$this->loadModel('score')->score('task', 'create', $taskID);
$mails[$i] = new stdclass();
$mails[$i]->taskID = $taskID;
$mails[$i]->actionID = $actionID;
}
$this->countTime($tasks->parent[0]);
$this->loadModel('score')->score('ajax', 'batchCreate');
return $mails;
}
@@ -601,7 +600,7 @@ class taskModel extends model
die(js::error('task#' . $taskID . dao::getError(true)));
}
}
$this->loadModel('score')->score('ajax', 'batchEdit');
return $allChanges;
}
@@ -886,6 +885,7 @@ class taskModel extends model
$this->countTime($oldTask->parent);
if($oldTask->story) $this->loadModel('story')->setStage($oldTask->story);
$this->loadModel('score')->score('task', 'finish', $taskID);
if(!dao::isError()) return common::createChanges($oldTask, $task);
}
@@ -940,7 +940,7 @@ class taskModel extends model
$data = new stdClass();
$data->status = 'closed';
$this->dao->update(TABLE_TASK)->data($data)->autoCheck()->where('parent')->eq($taskID)->exec();
$this->loadModel('score')->score('task', 'close', $taskID);
if($oldTask->story) $this->loadModel('story')->setStage($oldTask->story);
if(!dao::isError()) return common::createChanges($oldTask, $task);
}
+2
View File
@@ -107,6 +107,7 @@ class testcaseModel extends model
$caseID = $this->dao->lastInsertID();
$this->loadModel('file')->saveUpload('testcase', $caseID);
$parentStepID = 0;
$this->loadModel('score')->score('testcase', 'create', $caseID);
foreach($this->post->steps as $stepID => $stepDesc)
{
if(empty($stepDesc)) continue;
@@ -223,6 +224,7 @@ class testcaseModel extends model
unset($cases->keywords[$i]);
}
}
$this->loadModel('score')->score('ajax', 'batchCreate');
}
/**
+2
View File
@@ -911,6 +911,8 @@ class testtaskModel extends model
}
}
$this->loadModel('score')->score('testTask', 'runCase', $postData->case);
return $caseResult;
}
+4 -1
View File
@@ -46,6 +46,7 @@ class todoModel extends model
{
$todoID = $this->dao->lastInsertID();
$this->file->updateObjectID($this->post->uid, $todoID, 'todo');
$this->loadModel('score')->score('todo','create',$todoID);
return $todoID;
}
}
@@ -91,7 +92,9 @@ class todoModel extends model
echo js::error(dao::getError());
die(js::reload('parent'));
}
$this->loadModel('action')->create('todo', $this->dao->lastInsertID(), 'opened');
$todoID = $this->dao->lastInsertID();
$this->loadModel('action')->create('todo', $todoID, 'opened');
$this->loadModel('score')->score('todo', 'create', $todoID);
}
else
{
+5 -1
View File
@@ -52,7 +52,11 @@ class tutorial extends control
{
if($_POST && isset($_POST['finish'])) $finish = $_POST['finish'];
if($finish == 'keepAll') $this->send(array('result' => 'fail', 'message' => $this->lang->tutorial->ajaxSetError));
if($finish == 'keepAll')
{
$this->loadModel('score')->score('tutorial','keepAll');
$this->send(array('result' => 'fail', 'message' => $this->lang->tutorial->ajaxSetError));
}
$account = $this->app->user->account;
$this->session->set('tutorialMode', false);
+1 -1
View File
@@ -691,7 +691,7 @@ class user extends control
$this->session->set('user', $user);
$this->app->user = $this->session->user;
$this->loadModel('action')->create('user', $user->id, 'login');
$this->loadModel('score')->score('user','login');
/* Keep login. */
if($this->post->keepLogin) $this->user->keepLogin($user);
+3 -3
View File
@@ -408,7 +408,7 @@ class userModel extends model
}
}
if(!empty($user->password) and $user->account == $this->app->user->account) $this->app->user->password = $user->password;
$this->loadModel('score')->score('user','editProfile');
if(!dao::isError())
{
$this->loadModel('mail');
@@ -535,10 +535,10 @@ class userModel extends model
dao::$errors['originalPassword'][] = $this->lang->user->error->originalPassword;
return false;
}
$this->dao->update(TABLE_USER)->data($user)->autoCheck()->where('id')->eq((int)$userID)->exec();
$this->app->user->password = $user->password;
$this->app->user->modifyPassword = false;;
$this->app->user->modifyPassword = false;
$this->loadModel('score')->score('user','changePassword',$this->computePasswordStrength($this->post->password1));
}
/**
+17
View File
@@ -193,6 +193,11 @@ function showSearchMenu(objectType, objectID, module, method, extra)
{
$menu.find('#search').focus();
}
if(!$.cookie('ajax_quickDump'))
{
$.cookie('ajax_quickDump', 'on', {expires: config.cookieLife, path: config.webRoot});
$.get(createLink('score', 'ajax', "method=quickDump"));
}
}
/**
@@ -415,6 +420,7 @@ function setTreeBox()
function selectLang(lang)
{
$.cookie('lang', lang, {expires:config.cookieLife, path:config.webRoot});
$.get(createLink('score', 'ajax', "method=selectLang"));
location.href = removeAnchor(location.href);
}
@@ -427,6 +433,7 @@ function selectLang(lang)
function selectTheme(theme)
{
$.cookie('theme', theme, {expires:config.cookieLife, path:config.webRoot});
$.get(createLink('score', 'ajax', "method=selectTheme"));
location.href = removeAnchor(location.href);
}
@@ -1738,11 +1745,21 @@ function initHotKey()
{
/* left, go to pre object. */
var preLink = $('#pre').attr('href');
if(!$.cookie('ajax_lastNext'))
{
$.cookie('ajax_lastNext', 'on', {expires: config.cookieLife, path: config.webRoot});
$.get(createLink('score', 'ajax', "method=lastNext"));
}
if(preLink) location.href = preLink;
}).bind('keydown', 'right', function()
{
/* right, go to next object. */
var nextLink = $('#next').attr('href');
if(!$.cookie('ajax_lastNext'))
{
$.cookie('ajax_lastNext', 'on', {expires: config.cookieLife, path: config.webRoot});
$.get(createLink('score', 'ajax', "method=lastNext"));
}
if(nextLink) location.href = nextLink;
});
}