* Resolve confilict.

This commit is contained in:
liuchenglong
2023-05-06 01:51:00 +00:00
204 changed files with 5528 additions and 4160 deletions
+5 -3
View File
@@ -1,6 +1,11 @@
<?php
declare(strict_types=1);
if(!isset($config->programplan->create)) $config->programplan->create = new stdclass;
$config->programplan->create->form = array();
$config->programplan->create->formFields = array('planIDList', 'names', 'PM', 'percents', 'attributes', 'acl', 'milestone', 'begin', 'end', 'realBegan', 'realEnd', 'desc', 'orders', 'type');
foreach($config->programplan->create->formFields as $field) $config->programplan->create->form[$field] = array('required' => false, 'type' => 'array');
$config->programplan->edit = new stdClass();
$config->programplan->edit->form = array();
$config->programplan->edit->form['begin'] = array('required' => false, 'type' => 'string', 'default' => '0000-00-00');
@@ -9,6 +14,3 @@ $config->programplan->edit->form['realBegan'] = array('required' => false, 'type
$config->programplan->edit->form['realEnd'] = array('required' => false, 'type' => 'string', 'default' => '0000-00-00');
$config->programplan->edit->form['output'] = array('required' => false, 'type' => 'array', 'default' => array());
+20 -21
View File
@@ -148,7 +148,8 @@ class programplan extends control
$this->app->loadLang('project');
if($_POST)
{
$this->programplan->create($projectID, $this->productID, $planID);
$formData = form::data($this->config->programplan->create->form);
$this->programplan->create($formData, $projectID, $this->productID, $planID);
if(dao::isError())
{
$errors = dao::getError();
@@ -309,44 +310,42 @@ class programplan extends control
}
/**
* 处理甘特图拖拽事件数据。
* Response gantt drag event.
*
* @access public
* @return void
*/
public function ajaxResponseGanttDragEvent()
{
if(!empty($_POST))
{
if(!isset($_POST['id']) or empty($_POST['id'])) return $this->send(array('result' => 'fail', 'message' => ''));
$objectID = $_POST['id'];
if(empty($_POST['id']) || empty($_POST['type'])) return $this->send(array('result' => 'fail', 'message' => ''));
$this->loadModel('task')->updateEsDateByGantt($objectID, $_POST['type']);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$objectID = $_POST['id'];
$objectType = $_POST['type'];
$this->loadModel('task')->updateEsDateByGantt($objectID, $objectType);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success'));
}
return $this->send(array('result' => 'success'));
}
/**
* 处理甘特图移动事件数据。
* Response gantt move event.
*
* @access public
* @access public
* @return void
*/
public function ajaxResponseGanttMoveEvent()
{
if(!empty($_POST))
{
$idList = explode('-', $_POST['id']);
$taskID = $idList[1];
if(empty($_POST['id'])) return $this->send(array('result' => 'fail', 'message' => ''));
$this->loadModel('task')->updateOrderByGantt();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->loadModel('action')->create('task', $taskID, 'ganttMove');
return $this->send(array('result' => 'success'));
}
$idList = explode('-', $_POST['id']);
$taskID = !empty($idList[1]) ? $idList[1] : 0;
if(empty($taskID)) return $this->send(array('result' => 'fail', 'message' => ''));
$this->loadModel('task')->updateOrderByGantt();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->loadModel('action')->create('task', $taskID, 'ganttMove');
return $this->send(array('result' => 'success'));
}
/**
+71 -51
View File
@@ -13,19 +13,6 @@
<?php
class programplanModel extends model
{
/**
* Set menu.
*
* @param int $projectID
* @param int $productID
* @access public
* @return bool
*/
public function setMenu($projectID, $productID)
{
return true;
}
/**
* Get plan by id.
*
@@ -150,6 +137,7 @@ class programplanModel extends model
}
/**
* 获取甘特图页面数据。
* Get gantt data.
*
* @param int $executionID
@@ -160,27 +148,14 @@ class programplanModel extends model
* @access public
* @return string
*/
public function getDataForGantt($executionID, $productID, $baselineID = 0, $selectCustom = '', $returnJson = true)
public function getDataForGantt(int $executionID, int $productID, int $baselineID = 0, string $selectCustom = '', bool $returnJson = true): string
{
$this->loadModel('stage');
$this->loadModel('execution');
$plans = $this->getStage($executionID, $productID, 'all', 'order');
if($baselineID)
{
$baseline = $this->loadModel('cm')->getByID($baselineID);
$oldData = json_decode($baseline->data);
$oldPlans = $oldData->stage;
foreach($oldPlans as $id => $oldPlan)
{
if(!isset($plans[$id])) continue;
$plans[$id]->version = $oldPlan->version;
$plans[$id]->name = $oldPlan->name;
$plans[$id]->milestone = $oldPlan->milestone;
$plans[$id]->begin = $oldPlan->begin;
$plans[$id]->end = $oldPlan->end;
}
}
if($baselineID) $plans = $this->getBaselineData($baselineID, $plans);
$today = helper::today();
$datas = array();
@@ -380,6 +355,33 @@ class programplanModel extends model
return $returnJson ? json_encode($datas) : $datas;
}
/**
* 获取基线数据。
* Get baseline data.
*
* @param int $baselineID
* @param array $plans
* @access private
* @return array
*/
private function getBaselineData(int $baselineID, array $plans): array
{
$baseline = $this->loadModel('cm')->getByID($baselineID);
$oldData = json_decode($baseline->data);
$oldPlans = $oldData->stage;
foreach($oldPlans as $id => $oldPlan)
{
if(!isset($plans[$id])) continue;
$plans[$id]->version = $oldPlan->version;
$plans[$id]->name = $oldPlan->name;
$plans[$id]->milestone = $oldPlan->milestone;
$plans[$id]->begin = $oldPlan->begin;
$plans[$id]->end = $oldPlan->end;
}
return $plans;
}
/**
* Get gantt data group by assigned.
*
@@ -617,11 +619,11 @@ class programplanModel extends model
/**
* Process plans.
*
* @param int $plans
* @param array $plans
* @access public
* @return object
*/
public function processPlans($plans)
private function processPlans(array $plans)
{
foreach($plans as $planID => $plan) $plans[$planID] = $this->processPlan($plan);
return $plans;
@@ -683,42 +685,60 @@ class programplanModel extends model
}
/**
* Create a plan.
* 创建/设置一个项目阶段。
* Create/Set a project plan/phase.
*
* @param int $projectID
* @param int $productID
* @param int $parentID
* @param array $formData
* @param int $projectID
* @param int $productID
* @param int $parentID
* @access public
* @return bool
*/
public function create($projectID = 0, $productID = 0, $parentID = 0)
public function create(array $formData, int $projectID = 0, int $productID = 0, int $parentID = 0): bool
{
$data = (array)fixer::input('post')->get();
extract($data);
/* Get every value from formData without use extract(). */
$planIDList = $formData['planIDList'];
$names = $formData['names'];
$PM = $formData['PM'];
$percents = $formData['percents'];
$attributes = $formData['attributes'];
$acl = $formData['acl'];
$milestone = $formData['milestone'];
$begin = $formData['begin'];
$end = $formData['end'];
$realBegan = $formData['realBegan'];
$realEnd = $formData['realEnd'];
$desc = $formData['desc'];
$orders = $formData['orders'];
$type = $formData['type'];
$codes = $formData['codes'];
$output = $formData['output'];
/* Determine if a task has been created under the parent phase. */
if(!$this->isCreateTask($parentID)) return dao::$errors['message'][] = $this->lang->programplan->error->createdTask;
/* The child phase type setting is the same as the parent phase. */
$parentAttribute = '';
$parentPercent = 0;
if($parentID)
{
$parentStage = $this->getByID($parentID);
$parentAttribute = $parentStage->attribute;
$parentPercent = $parentStage->percent;
$parentACL = $parentStage->acl;
}
/* Remove empty items and get same items in array. */
$names = array_filter($names);
$sameNames = array_diff_assoc($names, array_unique($names));
$project = $this->loadModel('project')->getByID($projectID);
/* Check weather need to set code and compute same code. */
$setCode = (isset($this->config->setCode) and $this->config->setCode == 1) ? true : false;
$sameCodes = $setCode ? $this->checkCodeUnique($codes, isset($planIDList) ? $planIDList : '') : false;
/* Prepare the plans user inputted. Process the plan which names not empty only. */
$project = $this->loadModel('project')->getByID($projectID);
$setPercent = (isset($this->config->setPercent) and $this->config->setPercent == 1) ? true : false;
$datas = array();
$plans = array();
foreach($names as $key => $name)
{
if(empty($name)) continue;
@@ -729,8 +749,6 @@ class programplanModel extends model
$plan->project = $projectID;
$plan->parent = $parentID ? $parentID : $projectID;
$plan->name = $names[$key];
if($setCode) $plan->code = $codes[$key];
if($setPercent) $plan->percent = $percents[$key];
$plan->attribute = (empty($parentID) or $parentAttribute == 'mix') ? $attributes[$key] : $parentAttribute;
$plan->milestone = $milestone[$key];
$plan->output = empty($output[$key]) ? '' : implode(',', $output[$key]);
@@ -738,25 +756,26 @@ class programplanModel extends model
$plan->PM = empty($PM[$key]) ? '' : $PM[$key];
$plan->desc = empty($desc[$key]) ? '' : $desc[$key];
$plan->hasProduct = $project->hasProduct;
if($setCode) $plan->code = $codes[$key];
if($setPercent) $plan->percent = $percents[$key];
if(!empty($begin[$key])) $plan->begin = $begin[$key];
if(!empty($end[$key])) $plan->end = $end[$key];
if(!empty($realBegan[$key])) $plan->realBegan = $realBegan[$key];
if(!empty($realEnd[$key])) $plan->realEnd = $realEnd[$key];
$datas[] = $plan;
$plans[] = $plan;
}
if(empty($datas))
if(empty($plans))
{
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->name);
return false;
}
$totalPercent = 0;
$totalDevType = 0;
$milestone = 0;
foreach($datas as $index => $plan)
foreach($plans as $index => $plan)
{
if(!empty($sameNames) and in_array($plan->name, $sameNames)) dao::$errors[$index]['name'] = empty($type) ? $this->lang->programplan->error->sameName : str_replace($this->lang->execution->stage, '', $this->lang->programplan->error->sameName);
if($setCode and $sameCodes !== true and !empty($sameCodes) and in_array($plan->code, $sameCodes)) dao::$errors[$index]['code'] = sprintf($this->lang->error->repeat, $plan->type == 'stage' ? $this->lang->execution->code : $this->lang->code, $plan->code);
@@ -838,7 +857,7 @@ class programplanModel extends model
if(!isset($orders)) $orders = array();
asort($orders);
if(count($orders) < count($datas))
if(count($orders) < count($plans))
{
$orderIndex = empty($orders) ? 0 : count($orders);
$lastID = $this->dao->select('id')->from(TABLE_EXECUTION)->orderBy('id_desc')->fetch('id');
@@ -1602,13 +1621,14 @@ class programplanModel extends model
}
/**
* 获取阶段同一层级信息。
* Get plan's siblings.
*
* @param string|int|array $planIdList
* @param string|int|array $planIdList
* @access public
* @return array
*/
public function getSiblings($planIdList)
public function getSiblings(array|string|int $planIdList): array
{
if(is_numeric($planIdList)) $planIdList = (array)$planIdList;
+8
View File
@@ -1,5 +1,13 @@
<?php
declare(strict_types=1);
/**
* The tao file of programplan module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author lanzongjun <lanzongjun@easycorp.ltd>
* @link https://www.zentao.net
*/
class programplanTao extends programplanModel
{
+28 -12
View File
@@ -7,23 +7,39 @@ su('admin');
/**
title=测试 programplanModel->getByID();
timeout=0
cid=1
pid=1
获取阶段131 >> 阶段31,project31
获取阶段132 >> 阶段32,project32
获取阶段133 >> 阶段33,project33
获取阶段134 >> 阶段34,project34
获取阶段135 >> 阶段35,project35
- 判断项目阶段1的name是否为项目1
- 属性name @项目1
- 属性code @project1
- 判断项目阶段2的name是否为项目2
- 属性name @项目2
- 属性code @project2
- 判断项目阶段3的type是否为project属性type @project
- 判断项目阶段1的milestone,setMilestone在另外一种情况下是否为0
- 属性milestone @0
- 属性setMilestone @0
*/
$planIDList = array('131', '132', '133', '134', '135');
function initData()
{
zdTable('project')->config('getbyid')->gen(5);
}
initData();
$planIDList = array('1', '2' ,'3' ,'4', '5');
$programplan = new programplanTest();
r($programplan->getByIDTest($planIDList[0])) && p('name,code') && e('阶段31,project31'); // 获取阶段131
r($programplan->getByIDTest($planIDList[1])) && p('name,code') && e('阶段32,project32'); // 获取阶段132
r($programplan->getByIDTest($planIDList[2])) && p('name,code') && e('阶段33,project33'); // 获取阶段133
r($programplan->getByIDTest($planIDList[3])) && p('name,code') && e('阶段34,project34'); // 获取阶段134
r($programplan->getByIDTest($planIDList[4])) && p('name,code') && e('阶段35,project35'); // 获取阶段135
r($programplan->getByIDTest($planIDList[0])) && p('name,code') && e('项目1,project1'); // 判断项目阶段1的name是否为项目1
r($programplan->getByIDTest($planIDList[1])) && p('name,code') && e('项目2,project2'); // 判断项目阶段2的name是否为项目2
r($programplan->getByIDTest($planIDList[2])) && p('type') && e('project'); // 判断项目阶段3的type是否为project
r($programplan->getByIDTest($planIDList[0])) && p('milestone,setMilestone') && e('0,0'); // 判断项目阶段1的milestone,setMilestone在另外一种情况下是否为0
+4 -21
View File
@@ -5,33 +5,16 @@ include dirname(__FILE__, 2) . '/programplan.class.php';
zdTable('user')->gen(5);
su('admin');
$execution = zdTable('project');
$execution->id->range('1-5');
$execution->name->range('瀑布项目1,阶段a,阶段a子1,阶段a子1子1,阶段b');
$execution->type->range('project,stage{4}');
$execution->project->range('0,1{4}');
$execution->parent->range('0,1,2,3,1');
$execution->path->range("`,1,`,`,1,2,`,`,1,2,3,`,`,1,2,3,4,`,`,1,5,`");
$execution->status->range('doing,doing,doing,closed,suspended');
$execution->openedBy->range('admin,user1');
$execution->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
$execution->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
$execution->realBegan->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
$execution->gen(5);
/**
title=测试programplanModel->getSiblings();
cid=1
pid=1
测试id为2时获取兄弟阶段的的名称 >> 阶段b
测试id为2时获取自己兄弟阶段的个数 >> 1
测试id为4时获取自己兄弟阶段的个数 >> 0
pid=0
*/
$plan = new programplanTest();
zdTable('project')->config('getsiblings')->gen(5);
$plan = new programplanTest();
$topPlan = $plan->getSiblingsTest(2);
$topPlanCount = count($topPlan[2]);
@@ -0,0 +1,40 @@
title: zt_getbyid
author: shenshulong
version: '1.0'
fields:
- field: id
range: 1-5
- field: project
range: 1-5
- field: name
range: 1-5
prefix: '项目'
- field: code
range: 1-5
prefix: 'project'
- field: model
range: scrum
- field: parent
range: 0-3
- field: milestone
range: 0-1
- field: auth
range: '[]'
- field: type
range: 'project'
- field: grade
range: 1
- field: days
range: 1
- field: status
range: 'wait'
- field: desc
range: 1-5
prefix: '项目描述'
- field: budget
range: '100000,200000'
- field: budgetUnit
range: 'CNY'
- field: percent
range: '0-0'
@@ -0,0 +1,25 @@
title: zt_getsibiings
author: jukui
version: '1.0'
fields:
- field: id
range: 1-5
- field: project
range: 1-5
- field: name
range: '瀑布项目1,阶段a,阶段a子1,阶段a子1子1,阶段b'
- field: parent
range: '0,1,2,3,1'
- field: type
range: '0,1{4}'
- field: grade
range: 1
- field: days
range: 1
- field: status
range: 'doing,doing,doing,closed,suspended'
- field: desc
range: 1-5
prefix: '项目描述'
- field: path
range: "`,1,`,`,1,2,`,`,1,2,3,`,`,1,2,3,4,`,`,1,5,`"
@@ -19,6 +19,8 @@ class programplanTest
{
$object = $this->objectModel->getByID($planID);
if(!$object->setMilestone) $object->setMilestone = 0;
if(dao::isError()) return dao::getError();
return $object;
+8
View File
@@ -1,5 +1,13 @@
<?php
declare(strict_types=1);
/**
* The zen file of programplan module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author lanzongjun <lanzongjun@easycorp.ltd>
* @link https://www.zentao.net
*/
class programplanZen extends programplan
{
/**