Merge branch 'master' of https://git.zcorp.cc/easycorp/zentaopms
This commit is contained in:
@@ -26,24 +26,7 @@ $config->project->form->create['whitelist'] = array('type' => 'array', 'requir
|
||||
$config->project->form->create['auth'] = array('type' => 'array', 'required' => false, 'default' => '');
|
||||
$config->project->form->create['model'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
|
||||
$config->project->form->edit['parent'] = array('type' => 'int', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['name'] = array('type' => 'string', 'required' => true, 'filter' => 'trim');
|
||||
$config->project->form->edit['code'] = array('type' => 'string', 'required' => true, 'filter' => 'trim');
|
||||
$config->project->form->edit['multiple'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['hasProduct'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['PM'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['budget'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['budgetUnit'] = array('type' => 'string', 'required' => false, 'default' => 'CNY');
|
||||
$config->project->form->edit['begin'] = array('type' => 'date', 'required' => true);
|
||||
$config->project->form->edit['end'] = array('type' => 'date', 'required' => true);
|
||||
$config->project->form->edit['desc'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['acl'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['whitelist'] = array('type' => 'array', 'required' => false, 'default' => '', 'filter' => 'join');
|
||||
$config->project->form->edit['auth'] = array('type' => 'array', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['model'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['plans'] = array('type' => 'array', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['products'] = array('type' => 'array', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit['product'] = array('type' => 'array', 'required' => false, 'default' => '');
|
||||
$config->project->form->edit = $config->project->form->create;
|
||||
|
||||
$config->project->form->start['realBegan'] = array('type' => 'date', 'required' => true, 'filter' => 'trim');
|
||||
|
||||
|
||||
@@ -535,12 +535,13 @@ class project extends control
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$postData = form::data($this->config->project->form->edit);
|
||||
$project = $this->projectZen->prepareEditExtras($projectID, $postData);
|
||||
$postData = form::data($this->config->project->form->edit);
|
||||
$postExtras = $this->projectZen->prepareEditExtras($postData);
|
||||
$project = $this->projectZen->prepareProject($projectID, $postData, $postExtras);
|
||||
|
||||
$project->products = isset($project->products) ? array_filter($project->products) : $linkedProducts;
|
||||
|
||||
$changes = $this->project->update($projectID, $project, $postData);
|
||||
$changes = $this->project->update($projectID, $project, $postExtras);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
if($changes)
|
||||
|
||||
+42
-36
@@ -1233,7 +1233,7 @@ class projectModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查输入的$project 变量的branch和product是否合法。
|
||||
* 检查输入的$postData 变量的branch和product是否合法。
|
||||
* Check branch and product valid by project.
|
||||
*
|
||||
* @param int $projectID
|
||||
@@ -1241,13 +1241,13 @@ class projectModel extends model
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkBranchAndProductValid(int $projectID, object $project): bool
|
||||
public function checkBranchAndProductValid(int $projectID, object $project, object $postData): bool
|
||||
{
|
||||
$topProgramID = $this->loadModel('program')->getTopByID($project->parent);
|
||||
$multipleProducts = $this->loadModel('product')->getMultiBranchPairs($topProgramID);
|
||||
foreach($project->products as $index => $productID)
|
||||
foreach($postData->products as $index => $productID)
|
||||
{
|
||||
if(isset($multipleProducts[$productID]) and empty($project->branch[$index]))
|
||||
if(isset($multipleProducts[$productID]) and empty($postData->branch[$index]))
|
||||
{
|
||||
dao::$errors[] = $this->lang->project->emptyBranch;
|
||||
return false;
|
||||
@@ -1299,13 +1299,13 @@ class projectModel extends model
|
||||
* @param object $project
|
||||
* @param object $oldproject
|
||||
*/
|
||||
public function updateTeamMembersByProject(int $projectID, object $project, object $oldProject): bool
|
||||
public function updateTeamMembersByProject(int $projectID, object $project, object $oldProject, object $postExtras): bool
|
||||
{
|
||||
if($project->model != 'kanban') return true;
|
||||
if($postExtras->model == 'kanban') return true;
|
||||
/* Get oldProject's team and roles.*/
|
||||
$this->loadModel('user');
|
||||
$team = $this->user->getTeamMemberPairs($projectID, 'project');
|
||||
$members = $project->teamMembers;
|
||||
$members = $postExtras->teamMembers;
|
||||
array_push($members, $project->PM);
|
||||
$members = array_unique($members);
|
||||
$roles = $this->user->getUserRoles(array_values($members));
|
||||
@@ -1353,15 +1353,19 @@ class projectModel extends model
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function updateWhitelistByProject(int $projectID, object $project, object $oldProject, array $linkedProducts): bool
|
||||
public function updateWhitelistByProject(int $projectID, object $project, object $oldProject): bool
|
||||
{
|
||||
/* Check if whitelist shoud update .*/
|
||||
$whitelist = array_filter(explode(',', $project->whitelist));
|
||||
$oldWhitelist = explode(',', $oldProject->whitelist) and $oldWhitelist = array_filter($oldWhitelist);
|
||||
$oldWhitelist = array_filter(explode(',', $oldProject->whitelist));
|
||||
if(count($oldWhitelist) == count($whitelist) and !empty(array_diff($oldWhitelist, $whitelist)))
|
||||
{
|
||||
$this->loadModel('personnel')->updateWhitelist($whitelist, 'project', $projectID);
|
||||
if(!$oldProject->hasProduct) $this->loadModel('personnel')->updateWhitelist($whitelist, 'product', current($linkedProducts));
|
||||
if(!$oldProject->hasProduct)
|
||||
{
|
||||
$linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs();
|
||||
$this->loadModel('personnel')->updateWhitelist($whitelist, 'product', current($linkedProducts));
|
||||
}
|
||||
}
|
||||
|
||||
return !dao::isError();
|
||||
@@ -1377,14 +1381,14 @@ class projectModel extends model
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function unLinkProductsByProject(int $projectID, object $project, object $oldProject): bool
|
||||
public function unLinkProductsByProject(int $projectID, object $project, object $oldProject, object $postData): bool
|
||||
{
|
||||
$linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)
|
||||
->where('project')->eq($projectID)
|
||||
->fetchPairs();
|
||||
$oldProject->linkedProducts = implode(',', $linkedProducts);
|
||||
$project->linkedProducts = implode(',', $project->products);
|
||||
$unlinkedProducts = array_diff($linkedProducts, $project->products);
|
||||
$project->linkedProducts = implode(',', $postData->products);
|
||||
$unlinkedProducts = array_diff($linkedProducts, $postData->products);
|
||||
if(empty($unlinkedProducts)) return true;
|
||||
|
||||
$products = $this->dao->select('name')->from(TABLE_PRODUCT)
|
||||
@@ -1466,7 +1470,7 @@ class projectModel extends model
|
||||
* @access public
|
||||
* @return array|false
|
||||
*/
|
||||
public function update(int $projectID, object $project , object $postData): array|false
|
||||
public function update(int $projectID, object $project, object $postExtras): array|false
|
||||
{
|
||||
/* 通过id查老项目信息, 处理parent和图片字段。*/
|
||||
/* Fetch oldProject's info and get parent and file info.*/
|
||||
@@ -1480,32 +1484,23 @@ class projectModel extends model
|
||||
|
||||
/* 更新project表。*/
|
||||
/* Update project table.*/
|
||||
$result = $this->projectTao->doUpdate($projectID, $project, $oldProject);
|
||||
if(!$result) return false;
|
||||
|
||||
/* 如果是无产品项目,更新影子产品信息。*/
|
||||
/* If this is a project without product, update shadow product's info by project.*/
|
||||
if(!$oldProject->hasProduct)
|
||||
{
|
||||
/* If oldProject has no product and name or parent or acl has changed, update shadow product.*/
|
||||
if($oldProject->name != $project->name || $oldProject->parent != $project->parent or $oldProject->acl != $project->acl) $this->updateShadowProduct($project);
|
||||
|
||||
/* If oldProject has no product and status has changed to dong or closed updateShadowProductStatus.*/
|
||||
if($oldProject->status != $project->status && str_contains('doing,closed', $project->status)) $this->updateShadowProductStatus($projectID, $project->status);
|
||||
}
|
||||
$success = $this->projectTao->doUpdate($projectID, $project, $oldProject);
|
||||
if(!$success) return false;
|
||||
|
||||
/* 更新项目的关联信息。*/
|
||||
/* Update relation info of this project.*/
|
||||
$this->stageProduct($projectID, $oldProject->stageBy); // 更新关联的所有产品的阶段。
|
||||
$this->updateProducts($projectID, $project->product); // 更新关联的项目列表。
|
||||
$this->unLinkProductsByProject($projectID, $project, $oldProject); // 解除关联部分关联的产品信息。
|
||||
$this->updateProducts($projectID, $postExtras->products); // 更新关联的项目列表。
|
||||
$this->updateShadowProduct($project, $oldProject); // 更新影子产品关联信息。
|
||||
$this->unLinkProductsByProject($projectID, $project, $oldProject, $postExtras); // 解除关联部分关联的产品信息。
|
||||
$this->updateUserViewByProject($projectID, $project->acl); // 更新用户视图。
|
||||
$this->updateWhitelistByProject($projectID, $project, $oldProject, $linkedProducts); // 更新关联的白名单列表。
|
||||
$this->updateTeamMembersByProject($projectID, $project, $oldProject); // 更新关联的成员列表。
|
||||
$this->updatePlanIdListByProject($projectID, $project->plans); // 更新关联的计划列表。
|
||||
$this->updateWhitelistByProject($projectID, $project, $oldProject); // 更新关联的白名单列表。
|
||||
$this->updateTeamMembersByProject($projectID, $project, $oldProject, $postExtras); // 更新关联的成员列表。
|
||||
$this->updatePlanIdListByProject($projectID, $postExtras->plans); // 更新关联的计划列表。
|
||||
|
||||
$this->file->updateObjectID($this->post->uid, $projectID, 'project'); // 通过uid更新文件id。
|
||||
|
||||
|
||||
if($oldProject->parent != $project->parent) $this->loadModel('program')->fixPath($projectID, $project->parent, $oldProject->path, $oldProject->grade); // 更新项目从属路径。
|
||||
if(empty($oldProject->multiple) and $oldProject->model != 'waterfall') $this->loadModel('execution')->syncNoMultipleSprint($projectID); // 无迭代的非瀑布项目需要更新。
|
||||
|
||||
@@ -1750,17 +1745,28 @@ class projectModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果是无产品项目,更新影子产品信息。
|
||||
* Update shadow product for its project.
|
||||
*
|
||||
* @param object $project
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function updateShadowProduct($project)
|
||||
public function updateShadowProduct(object $project, object $oldProject): bool
|
||||
{
|
||||
$product = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($project->id)->fetch('product');
|
||||
$topProgram = !empty($project->parent) ? $this->loadModel('program')->getTopByID($project->parent) : 0;
|
||||
$this->dao->update(TABLE_PRODUCT)->set('name')->eq($project->name)->set('program')->eq($topProgram)->set('acl')->eq($project->acl)->where('id')->eq($product)->exec();
|
||||
/* If this is a project without product, update shadow product's info by project.*/
|
||||
if($oldProject->hasProduct) return true;
|
||||
|
||||
/* If oldProject has no product and name or parent or acl has changed, update shadow product.*/
|
||||
if($oldProject->name != $project->name || $oldProject->parent != $project->parent or $oldProject->acl != $project->acl)
|
||||
{
|
||||
$product = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($project->id)->fetch('product');
|
||||
$topProgram = !empty($project->parent) ? $this->loadModel('program')->getTopByID($project->parent) : 0;
|
||||
$this->dao->update(TABLE_PRODUCT)->set('name')->eq($project->name)->set('program')->eq($topProgram)->set('acl')->eq($project->acl)->where('id')->eq($product)->exec();
|
||||
}
|
||||
|
||||
/* If oldProject has no product and status has changed to dong or closed updateShadowProductStatus.*/
|
||||
if($oldProject->status != $project->status && str_contains('doing,closed', $project->status)) $this->updateShadowProductStatus($projectID, $project->status);
|
||||
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
+25
-4
@@ -91,14 +91,14 @@ class projectZen extends project
|
||||
}
|
||||
|
||||
/**
|
||||
* Append extras data to post data.
|
||||
* Append $project to post data.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param object $postData
|
||||
* @access protected
|
||||
* @return object|false
|
||||
*/
|
||||
protected function prepareEditExtras(int $projectID, object $postData): object|false
|
||||
protected function prepareProject(int $projectID, object $postData, object $postExtras): object|false
|
||||
{
|
||||
$project = $postData->setDefault('team', $this->post->name)
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
@@ -108,14 +108,16 @@ class projectZen extends project
|
||||
->setIF($this->post->delta == 999, 'days', 0)
|
||||
->setIF($this->post->future, 'budget', 0)
|
||||
->setIF($this->post->budget != 0, 'budget', round((float)$this->post->budget, 2))
|
||||
->join('whitelist', ',')
|
||||
->join('auth', ',')
|
||||
->stripTags($this->config->project->editor->edit['id'], $this->config->allowedTags)
|
||||
->get();
|
||||
|
||||
/* Check if products and branch valid by project.*/
|
||||
if($project->product && !$this->project->checkBranchAndProductValid($projectID, $project)) return false;
|
||||
if($postExtras->products && !$this->project->checkBranchAndProductValid($projectID, $project, $postExtras)) return false;
|
||||
|
||||
/* Check if products not empty.*/
|
||||
if(!$this->checkProductsNotEmpty($project->products)) return false;
|
||||
if(!$this->checkProductsNotEmpty($postExtras->products)) return false;
|
||||
|
||||
/* Check if work days legtimate.*/
|
||||
if(!$this->checkWorkdaysLegtimate($project)) return false;
|
||||
@@ -127,6 +129,25 @@ class projectZen extends project
|
||||
return $project;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append extra data to postData.
|
||||
*
|
||||
* @param object $project
|
||||
* @param object $rawdata
|
||||
* @access protected
|
||||
* @return bool
|
||||
*/
|
||||
protected function prepareEditExtras(object $postData): object
|
||||
{
|
||||
$postExtras = new stdclass();
|
||||
$postExtras->plans = $postData->rawdata->plans;
|
||||
$postExtras->model = $postData->rawdata->model;
|
||||
$postExtras->products = $postData->rawdata->products;
|
||||
$postExtras->teamMembers = $postExtras->model == 'kanban' ? $postData->rawdata->teamMembers : array();
|
||||
|
||||
return $postExtras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check product and branch not empty.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user