* change for multi task teams.

This commit is contained in:
wangyidong
2022-08-17 16:01:41 +08:00
parent 28328da15c
commit 6d987182a8
6 changed files with 79 additions and 97 deletions
+3 -2
View File
@@ -5,7 +5,8 @@ CREATE TABLE `zt_taskteam` (
`estimate` decimal(12,2) NOT NULL,
`consumed` decimal(12,2) NOT NULL,
`left` decimal(12,2) NOT NULL,
`type` char(10) NOT NULL DEFAULT 'new',
`order` tinyint(3) NOT NULL,
PRIMARY KEY (`id`)
PRIMARY KEY (`id`),
KEY `task` (`task`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_taskteam` ADD INDEX `task` (`task`);
+2 -1
View File
@@ -2746,8 +2746,9 @@ class executionModel extends model
public function getTeamSkip($teams, $begin, $end)
{
$members = array();
foreach($teams as $account => $team)
foreach($teams as $team)
{
$account = $team->account;
if($account == $end) break;
if(!empty($begin) and $account != $begin and empty($members)) continue;
+1 -17
View File
@@ -571,23 +571,7 @@ $('#modalTeam .btn').click(function()
var team = '';
var time = 0;
var error = false;
/* Unique team. */
values = [];
$('select[name^=team]').each(function(i)
{
value = $(this).val();
if(value == '') return;
if($.inArray(value, values) >= 0)
{
$(this).closest('tr').addClass('hidden');
return;
}
values.push(value);
})
$('select[name^=team]').closest('tr.hidden').remove();
var mode = $('#mode').val();
$('select[name^=team]').each(function()
{
+1 -17
View File
@@ -159,22 +159,6 @@ $(document).ready(function()
$('#confirmButton').click(function()
{
/* Unique team. */
var values = [];
$('select[name^=team]').each(function(i)
{
value = $(this).val();
if(value == '') return;
if($.inArray(value, values) >= 0)
{
$(this).closest('tr').addClass('hidden');
return;
}
values.push(value);
});
$('select[name^=team]').closest('tr.hidden').remove();
var memberCount = '';
var totalEstimate = 0;
var totalConsumed = oldConsumed;
@@ -288,6 +272,6 @@ function updateAssignedTo()
}
$('#assignedTo').html(html);
if(multiple && mode == 'linear' && $('#modalTeam tr.member-doing').length == 0 && $('#modalTeam tr.member-wait').length >= 1) $('[name=assignedTo]').val($$('#modalTeam tr.member-wait:first').find('select[name^=team]:first').val());
if(multiple && mode == 'linear' && $('#modalTeam tr.member-doing').length == 0 && $('#modalTeam tr.member-wait').length >= 1) $('[name=assignedTo]').val($('#modalTeam tr.member-wait:first').find('select[name^=team]:first').val());
$('#assignedTo').trigger('chosen:updated');
}
+65 -56
View File
@@ -229,26 +229,26 @@ class taskModel extends model
{
foreach($this->post->team as $row => $account)
{
if(empty($account) or isset($team[$account])) continue;
if(empty($account)) continue;
$member = new stdClass();
$member->account = $account;
$member->estimate = $this->post->teamEstimate[$row] ? (float)$this->post->teamEstimate[$row] : 0;
$member->left = $member->estimate;
$member->order = $row;
$teams[$account] = $member;
}
}
$member->task = $taskID;
if(!empty($teams))
{
foreach($teams as $team)
$memberMethod = ($task->mode == 'multi' and isset($teams[$account])) ? 'update' : 'insert';
$this->manageTaskTeam($member, $memberMethod);
$teams[$account] = $account;
}
if($teams)
{
$team->task = $taskID;
$this->dao->insert(TABLE_TASKTEAM)->data($team)->autoCheck()->exec();
$task->id = $taskID;
$this->computeHours4Multiple($task);
}
$task->id = $taskID;
$this->computeHours4Multiple($task);
}
if(!dao::isError()) $this->loadModel('score')->create('task', 'create', $taskID);
@@ -784,14 +784,15 @@ class taskModel extends model
{
if(!$oldTask) return false;
if(empty($team)) $team = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($oldTask->id)->orderBy('order')->fetchAll('account');
if(empty($team)) $team = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($oldTask->id)->orderBy('order')->fetchAll();
if(!empty($team))
{
$now = helper::now();
$teams = array_keys($team);
$oldTeam = zget($oldTask, 'team', array());
$members = array_map(function($member){ return $member->account; }, $team);
$currentTask = !empty($task) ? $task : new stdclass();
if(!isset($currentTask->status)) $currentTask->status = $oldTask->status;
if(empty($oldTask->team)) $oldTask->team = $team;
$oldTask->team = $team;
$currentTask->assignedTo = $oldTask->assignedTo;
if(!empty($_POST['assignedTo']) and is_string($_POST['assignedTo']))
@@ -800,7 +801,7 @@ class taskModel extends model
}
else
{
$currentTask->assignedTo = $this->getAssignedTo4Multi($teams, $oldTask);
$currentTask->assignedTo = $this->getAssignedTo4Multi($members, $oldTask);
if($oldTask->assignedTo != $currentTask->assignedTo) $currentTask->assignedDate = $now;
}
@@ -814,6 +815,7 @@ class taskModel extends model
$currentTask->left += (float)$member->left;
}
$oldTask->team = $oldTeam;
if($this->app->rawMethod == 'edit' and empty($oldTask->team) and isset($oldTask->consumed)) $currentTask->consumed += (float)$oldTask->consumed;
if(!empty($task))
@@ -868,6 +870,30 @@ class taskModel extends model
}
}
/**
* Manage multi task team members.
*
* @param object $member
* @param string $method insert|update
* @access public
* @return void
*/
public function manageTaskTeam($member, $method)
{
if($method == 'update')
{
$this->dao->update(TABLE_TASKTEAM)->set("estimate= estimate + {$member->estimate}")
->set("`left` = `left` + {$member->left}")
->where('task')->eq($member->task)
->andWhere('account')->eq($member->account)
->exec();
}
elseif($method == 'insert')
{
$this->dao->insert(TABLE_TASKTEAM)->data($member)->autoCheck()->exec();
}
}
/**
* Update a task.
*
@@ -948,7 +974,7 @@ class taskModel extends model
->stripTags($this->config->task->editor->edit['id'], $this->config->allowedTags)
->cleanINT('execution,story,module')
->join('mailto', ',')
->remove('comment,files,labels,uid,multiple,team,teamEstimate,teamConsumed,teamLeft,contactListMenu')
->remove('comment,files,labels,uid,multiple,team,teamEstimate,teamConsumed,teamLeft,source,contactListMenu')
->get();
if($task->consumed < $oldTask->consumed) return print(js::error($this->lang->task->error->consumedSmall));
@@ -964,49 +990,33 @@ class taskModel extends model
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->edit['id'], $this->post->uid);
$teams = array();
if($this->post->multiple and count(array_unique(array_filter($this->post->team))) > 1)
if($this->post->multiple and count(array_filter($this->post->team)) > 1)
{
if(strpos(',done,closed,cancel,', ",{$task->status},") === false && $this->post->assignedTo && !in_array($this->post->assignedTo, $this->post->team))
{
dao::$errors[] = $this->lang->task->error->assignedTo;
return false;
}
$this->dao->delete()->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->exec();
foreach($this->post->team as $row => $account)
{
if(empty($account) or isset($team[$account])) continue;
if(empty($account)) continue;
$source = $this->post->source[$row];
$member = new stdClass();
$member->account = $account;
$member->task = $taskID;
$member->order = $row;
$member->type = (!empty($source) and $source != $account) ? 'replace' : 'new';
$member->account = $account;
$member->estimate = $this->post->teamEstimate[$row] ? $this->post->teamEstimate[$row] : 0;
$member->consumed = $this->post->teamConsumed[$row] ? $this->post->teamConsumed[$row] : 0;
$member->left = $this->post->teamLeft[$row] === '' ? 0 : $this->post->teamLeft[$row];
$member->order = $row;
$teams[$account] = $member;
if($task->status == 'done') $member->left = 0;
}
}
/* Save team. */
$this->dao->delete()->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->exec(); if(!empty($teams))
{
foreach($teams as $member) $this->dao->insert(TABLE_TASKTEAM)->data($member)->autoCheck()->exec();
$memberMethod = ($oldTask->mode == 'multi' and isset($teams[$account])) ? 'update' : 'insert';
$this->manageTaskTeam($member, $memberMethod);
/* Assign the left hours to zero who will be skipped. */
$skipMembers = $this->loadModel('execution')->getTeamSkip($oldTask->team, $oldTask->assignedTo, isset($task->assignedTo) ? $task->assignedTo : $oldTask->assignedTo);
foreach($skipMembers as $account => $team) $this->dao->update(TABLE_TASKTEAM)->set('left')->eq(0)->where('task')->eq($taskID)->andWhere('account')->eq($account)->exec();
$task = $this->computeHours4Multiple($oldTask, $task, array(), $autoStatus = false);
if($task->status == 'wait')
{
reset($teams);
$task->assignedTo = key($teams);
$teams[$account] = $account;
}
if(!empty($teams)) $task = $this->computeHours4Multiple($oldTask, $task, array(), $autoStatus = false);
}
else
{
$task->mode = '';
}
if(empty($teams)) $task->mode = '';
$execution = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($task->execution)->fetch();
$requiredFields = "," . $this->config->task->edit->requiredFields . ",";
@@ -2227,7 +2237,7 @@ class taskModel extends model
/* Check parent Task. */
if($task->parent > 0) $task->parentName = $this->dao->findById($task->parent)->from(TABLE_TASK)->fetch('name');
$task->team = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->orderBy('order')->fetchAll('account');
$task->team = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->orderBy('order')->fetchAll('id');
foreach($children as $child) $child->team = array();
$task = $this->loadModel('file')->replaceImgURL($task, 'desc');
@@ -2363,7 +2373,7 @@ class taskModel extends model
if(empty($tasks)) return array();
$taskList = array_keys($tasks);
$taskTeam = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->in($taskList)->fetchGroup('root');
$taskTeam = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->in($taskList)->fetchGroup('task');
if(!empty($taskTeam))
{
foreach($taskTeam as $taskID => $team) $tasks[$taskID]->team = $team;
@@ -3666,19 +3676,18 @@ class taskModel extends model
public function getAssignedTo4Multi($users, $task)
{
if(empty($task->team)) return $task->assignedTo;
if(empty($task->mode != 'linear')) return $task->assignedTo;
if($task->mode != 'linear') return $task->assignedTo;
$teamHours = $task->team;
$teamHours = array_values($task->team);
/* Process user */
if(!is_array($users)) $users = explode(',', trim($users, ','));
$users = array_values($users);
$isInList = (!$current || !in_array($current, $users) || array_search($current, $users) == (count($users) - 1))
foreach($users as $account)
{
if(isset($teamHours[$account]) and $$teamHours[$account]->consumed > 0 and $teamHours[$account]->left == 0) continue;
return $account;
$users = array_values($users);
foreach($users as $i => $account)
{
if(isset($teamHours[$i]) and $teamHours[$i]->consumed > 0 and $teamHours[$i]->left == 0) continue;
return $account;
}
return $task->openedBy;
+7 -4
View File
@@ -139,7 +139,7 @@ foreach(explode(',', $config->task->edit->requiredFields) as $field)
<?php endif;?>
<tr>
<th><?php echo $lang->task->assignedTo;?></th>
<?php $disableAssignedTo = (!empty($task->team) and ($task->mode == 'linear' or $task->assignedTo != $this->app->user->account)) ? "disabled='disabled'" : '';?>
<?php $disableAssignedTo = (!empty($task->team) and $task->mode == 'linear') ? "disabled='disabled'" : '';?>
<?php
$taskMembers = array();
if(!empty($task->team))
@@ -160,8 +160,7 @@ foreach(explode(',', $config->task->edit->requiredFields) as $field)
</tr>
<tr class="modeBox <?php echo $task->mode ? '' : 'hidden';?>">
<th><?php echo $lang->task->mode;?></th>
<?php $disabledMode = isset($task->team[$app->user->account]) ? '' : "disabled='disabled'"?>
<td><?php echo html::select('mode', $lang->task->modeList, $task->mode, "class='form-control chosen' $disabledMode onchange='updateAssignedTo()'");?></td>
<td><?php echo zget($lang->task->modeList, $task->mode) . html::hidden('mode', $task->mode);?></td>
</tr>
<tr class='<?php echo empty($task->team) ? 'hidden' : ''?>' id='teamTr'>
<th><?php echo $lang->task->team;?></th>
@@ -293,6 +292,7 @@ foreach(explode(',', $config->task->edit->requiredFields) as $field)
<tr class='member-<?php echo $memberStatus;?>'>
<td class='w-250px'>
<?php echo html::select("team[]", $members, $member->account, "class='form-control chosen'" . ($memberDisabled ? ' disabled' : ''))?>
<?php echo html::hidden("source[]", $member->account);?>
<?php if($memberDisabled) echo html::hidden("team[]", $member->account);?>
</td>
<td>
@@ -313,7 +313,10 @@ foreach(explode(',', $config->task->edit->requiredFields) as $field)
</tr>
<?php endforeach;?>
<tr class='template'>
<td class='w-250px'><?php echo html::select("team[]", $members, '', "class='form-control chosen'")?></td>
<td class='w-250px'>
<?php echo html::select("team[]", $members, '', "class='form-control chosen'")?>
<?php echo html::hidden("source[]", '');?>
</td>
<td>
<div class='input-group'>
<span class="input-group-addon <?php echo zget($requiredFields, 'estimate', '', ' required');?>"><?php echo $lang->task->estimate?></span>