Merge branch 'zentaopms_284' of https://gitlab.zcorp.cc/easycorp/zentaopms into tsj_sortable

This commit is contained in:
tianshujie
2023-02-14 13:32:06 +08:00
27 changed files with 277 additions and 53 deletions
+5
View File
@@ -58,6 +58,11 @@ $config->programplan->customCreateFields = 'PM,percent,attribute,acl,milestone,r
$config->programplan->custom = new stdclass();
$config->programplan->custom->createFields = 'PM,percent,attribute,acl,milestone';
$config->programplan->customAgilePlusCreateFields = 'PM,milestone,acl,desc';
$config->programplan->customAgilePlus = new stdclass();
$config->programplan->customAgilePlus->createFields = 'PM,milestone,acl,desc';
$config->programplan->custom->customGanttFields = 'PM,deadline,status,realBegan,realEnd,progress,taskProgress,estimate,consumed,delay,delayDays';
$config->programplan->ganttCustom = new stdclass();
$config->programplan->ganttCustom->ganttFields = 'PM,deadline';
+29 -7
View File
@@ -138,10 +138,11 @@ class programplan extends control
* @param int $projectID
* @param int $productID
* @param int $planID
* @param string $executionType
* @access public
* @return void
*/
public function create($projectID = 0, $productID = 0, $planID = 0)
public function create($projectID = 0, $productID = 0, $planID = 0, $executionType = 'stage')
{
$this->commonAction($projectID, $productID);
$this->app->loadLang('project');
@@ -165,10 +166,27 @@ class programplan extends control
$this->view->position[] = html::a($this->createLink('programplan', 'browse', "projectID=$projectID"), $project->name);
$this->view->position[] = $this->lang->programplan->create;
$visibleFields = array();
$requiredFields = array();
foreach(explode(',', $this->config->programplan->customCreateFields) as $field) $customFields[$field] = $this->lang->programplan->$field;
$showFields = $this->config->programplan->custom->createFields;
$executions = !empty($planID) ? $this->loadModel('execution')->getChildExecutions($planID) : array();
$plans = $this->programplan->getStage($planID ? $planID : $projectID, $this->productID, 'parent');
if(!empty($planID) and !empty($plans))
{
$executionType = 'stage';
unset($this->lang->programplan->typeList['agileplus']);
}
if(!empty($planID) and !empty($executions) and empty($plans))
{
$executionType = 'agileplus';
unset($this->lang->programplan->typeList['stage']);
}
$visibleFields = array();
$requiredFields = array();
$custom = $executionType == 'stage' ? 'custom' : 'customAgilePlus';
$customCreateFields = $executionType == 'stage' ? 'customCreateFields' : 'customAgilePlusCreateFields';
foreach(explode(',', $this->config->programplan->$customCreateFields) as $field) $customFields[$field] = $this->lang->programplan->$field;
$showFields = $this->config->programplan->$custom->createFields;
foreach(explode(',', $showFields) as $field)
{
if($field) $visibleFields[$field] = '';
@@ -179,19 +197,23 @@ class programplan extends control
if($field)
{
$requiredFields[$field] = '';
if(strpos(",{$this->config->programplan->customCreateFields},", ",{$field},") !== false) $visibleFields[$field] = '';
if(strpos(",{$this->config->programplan->$customCreateFields},", ",{$field},") !== false) $visibleFields[$field] = '';
}
}
if($executionType != 'stage') unset($this->lang->execution->typeList[''], $this->lang->execution->typeList['stage']);
$this->view->productList = $productList;
$this->view->project = $project;
$this->view->productID = $productID ? $productID : key($productList);
$this->view->stages = empty($planID) ? $this->loadModel('stage')->getStages('id_asc') : array();
$this->view->programPlan = $programPlan;
$this->view->plans = $this->programplan->getStage($planID ? $planID : $projectID, $this->productID, 'parent', 'order_asc');
$this->view->plans = empty($executions) ? $this->programplan->getStage($planID ? $planID : $projectID, $this->productID, 'parent', 'order_asc') : $executions;
$this->view->planID = $planID;
$this->view->type = 'lists';
$this->view->executionType = $executionType;
$this->view->PMUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $project->PM);
$this->view->custom = $custom;
$this->view->customFields = $customFields;
$this->view->showFields = $showFields;
$this->view->visibleFields = $visibleFields;
+2
View File
@@ -13,6 +13,8 @@ function addItem(obj)
newItem.find('.form-date').datepicker();
$("#output" + itemIndex).picker();
$("#PM" + itemIndex).picker();
$("#type" + itemIndex).chosen();
$("#type_i__chosen").remove();
itemIndex ++;
}
+6
View File
@@ -64,6 +64,7 @@ $lang->programplan->delay = 'Delay';
$lang->programplan->delayDays = 'Delay days';
$lang->programplan->settingGantt = 'Gantt Setting';
$lang->programplan->viewSetting = 'Setting';
$lang->programplan->desc = 'Description';
$lang->programplan->errorBegin = "Project begin date: %s, begin date should be >= project begin date.";
$lang->programplan->errorEnd = "Project end date: %s, end date should be <= project end date.";
@@ -79,6 +80,10 @@ $lang->programplan->delayList = array();
$lang->programplan->delayList[1] = 'Yes';
$lang->programplan->delayList[0] = 'No';
$lang->programplan->typeList = array();
$lang->programplan->typeList['stage'] = 'Stage';
$lang->programplan->typeList['agileplus'] = 'Sprint/Kanban';
$lang->programplan->noData = 'No Data';
$lang->programplan->children = 'Sub Plan';
$lang->programplan->childrenAB = 'Child';
@@ -113,6 +118,7 @@ $lang->programplan->error->sameName = 'Stage name cannot be the same!';
$lang->programplan->error->sameCode = 'Stage code cannot be the same!';
$lang->programplan->error->taskDrag = 'The %s task cannot be dragged';
$lang->programplan->error->planDrag = 'The %s stage cannot be dragged';
$lang->programplan->error->notStage = 'Sprint/Kanban cannot create a sub stage.';
$lang->programplan->ganttBrowseType['gantt'] = 'Group by Stage';
$lang->programplan->ganttBrowseType['assignedTo'] = 'Group by AssignedTo';
+6
View File
@@ -64,6 +64,7 @@ $lang->programplan->delay = 'Delay';
$lang->programplan->delayDays = 'Delay days';
$lang->programplan->settingGantt = 'Gantt Setting';
$lang->programplan->viewSetting = 'Setting';
$lang->programplan->desc = 'Description';
$lang->programplan->errorBegin = "Project begin date: %s, begin date should be >= project begin date.";
$lang->programplan->errorEnd = "Project end date: %s, end date should be <= project end date.";
@@ -79,6 +80,10 @@ $lang->programplan->delayList = array();
$lang->programplan->delayList[1] = 'Yes';
$lang->programplan->delayList[0] = 'No';
$lang->programplan->typeList = array();
$lang->programplan->typeList['stage'] = 'Stage';
$lang->programplan->typeList['agileplus'] = 'Sprint/Kanban';
$lang->programplan->noData = 'No Data';
$lang->programplan->children = 'Sub Plan';
$lang->programplan->childrenAB = 'Child';
@@ -113,6 +118,7 @@ $lang->programplan->error->sameName = 'Stage name cannot be the same!';
$lang->programplan->error->sameCode = 'Stage code cannot be the same!';
$lang->programplan->error->taskDrag = 'The %s task cannot be dragged';
$lang->programplan->error->planDrag = 'The %s stage cannot be dragged';
$lang->programplan->error->notStage = 'Sprint/Kanban cannot create a sub stage.';
$lang->programplan->ganttBrowseType['gantt'] = 'Group by Stage';
$lang->programplan->ganttBrowseType['assignedTo'] = 'Group by AssignedTo';
+6
View File
@@ -64,6 +64,7 @@ $lang->programplan->delay = 'Delay';
$lang->programplan->delayDays = 'Delay days';
$lang->programplan->settingGantt = 'Gantt Setting';
$lang->programplan->viewSetting = 'Setting';
$lang->programplan->desc = 'Description';
$lang->programplan->errorBegin = "Project begin date: %s, begin date should be >= project begin date.";
$lang->programplan->errorEnd = "Project end date: %s, end date should be <= project end date.";
@@ -79,6 +80,10 @@ $lang->programplan->delayList = array();
$lang->programplan->delayList[1] = 'Yes';
$lang->programplan->delayList[0] = 'No';
$lang->programplan->typeList = array();
$lang->programplan->typeList['stage'] = 'Stage';
$lang->programplan->typeList['agileplus'] = 'Sprint/Kanban';
$lang->programplan->noData = 'No Data';
$lang->programplan->children = 'Sub Plan';
$lang->programplan->childrenAB = 'Child';
@@ -113,6 +118,7 @@ $lang->programplan->error->sameName = 'Stage name cannot be the same!';
$lang->programplan->error->sameCode = 'Stage code cannot be the same!';
$lang->programplan->error->taskDrag = 'The %s task cannot be dragged';
$lang->programplan->error->planDrag = 'The %s stage cannot be dragged';
$lang->programplan->error->notStage = 'Sprint/Kanban cannot create a sub stage.';
$lang->programplan->ganttBrowseType['gantt'] = 'Group by Stage';
$lang->programplan->ganttBrowseType['assignedTo'] = 'Group by AssignedTo';
+6
View File
@@ -64,6 +64,7 @@ $lang->programplan->delay = '是否延期';
$lang->programplan->delayDays = '延期天数';
$lang->programplan->settingGantt = '设置甘特图';
$lang->programplan->viewSetting = '显示设置';
$lang->programplan->desc = '描述';
$lang->programplan->errorBegin = '阶段的开始时间不能小于所属项目的开始时间%s';
$lang->programplan->errorEnd = '阶段的结束时间不能大于所属项目的结束时间%s';
@@ -79,6 +80,10 @@ $lang->programplan->delayList = array();
$lang->programplan->delayList[1] = '是';
$lang->programplan->delayList[0] = '否';
$lang->programplan->typeList = array();
$lang->programplan->typeList['stage'] = '阶段';
$lang->programplan->typeList['agileplus'] = '迭代/看板';
$lang->programplan->noData = '暂无数据。';
$lang->programplan->children = '二级计划';
$lang->programplan->childrenAB = '子';
@@ -113,6 +118,7 @@ $lang->programplan->error->sameName = '阶段名称不能相同!';
$lang->programplan->error->sameCode = '阶段代号不能相同!';
$lang->programplan->error->taskDrag = '%s的任务不可以拖动';
$lang->programplan->error->planDrag = '%s的阶段不可以拖动';
$lang->programplan->error->notStage = '迭代/看板不支持创建子阶段';
$lang->programplan->ganttBrowseType['gantt'] = '按阶段分组';
$lang->programplan->ganttBrowseType['assignedTo'] = '按指派给分组';
+11 -5
View File
@@ -710,7 +710,8 @@ class programplanModel extends model
if(!$this->checkNameUnique($names))
{
dao::$errors['message'][] = $this->lang->programplan->error->sameName;
$this->app->loadLang('execution');
dao::$errors['message'][] = empty($type) ? $this->lang->programplan->error->sameName : str_replace($this->lang->execution->stage, '', $this->lang->programplan->error->sameName);;
return false;
}
@@ -731,7 +732,7 @@ class programplanModel extends model
$plan = new stdclass();
$plan->id = isset($planIDList[$key]) ? $planIDList[$key] : '';
$plan->type = 'stage';
$plan->type = empty($type[$key]) ? 'stage' : $type[$key];
$plan->project = $projectID;
$plan->parent = $parentID ? $parentID : $projectID;
$plan->name = $names[$key];
@@ -746,6 +747,7 @@ class programplanModel extends model
$plan->output = empty($output[$key]) ? '' : implode(',', $output[$key]);
$plan->acl = empty($parentID) ? $acl[$key] : $parentACL;
$plan->PM = empty($PM[$key]) ? '' : $PM[$key];
$plan->desc = empty($desc[$key]) ? '' : $desc[$key];
$plan->hasProduct = $project->hasProduct;
$datas[] = $plan;
@@ -1587,19 +1589,23 @@ class programplanModel extends model
*
* @param int $planID
* @param string $attribute
* @param bool $withDeleted
* @access public
* @return bool
*/
public function updateSubStageAttr($planID, $attribute)
public function updateSubStageAttr($planID, $attribute, $withDeleted = false)
{
if($attribute == 'mix') return true;
$subStageList = $this->dao->select('id')->from(TABLE_EXECUTION)->where('parent')->eq($planID)->andWhere('deleted')->eq(0)->fetchAll('id');
$subStageList = $this->dao->select('id')->from(TABLE_EXECUTION)
->where('parent')->eq($planID)
->beginIF(!$withDeleted)->andWhere('deleted')->eq(0)->fi()
->fetchAll('id');
$this->dao->update(TABLE_EXECUTION)->set('attribute')->eq($attribute)->where('id')->in(array_keys($subStageList))->exec();
foreach($subStageList as $childID => $subStage)
{
$this->updateSubStageAttr($childID, $attribute);
$this->updateSubStageAttr($childID, $attribute, $withDeleted);
}
}
}
+41 -16
View File
@@ -41,27 +41,45 @@
<?php endif;?>
</div>
</div>
<?php $hideAttribute = ($planID == 0 and isset($visibleFields['attribute'])) ? '' : ' hidden'?>
<?php $attrAlign = $enableOptionalAttr ? '' : 'text-center';?>
<?php $class = $planID == 0 ? '' : "disabled='disabled'"?>
<?php $name = $planID == 0 ? $lang->programplan->name : $lang->programplan->subStageName;?>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<?php if(!empty($planID)):?>
<div class="pull-left">
<div class='btn-group'>
<a href='javascript:;' class='btn btn-link btn-limit' data-toggle='dropdown'><span class='text' title='<?php echo zget($lang->programplan->typeList, $executionType);?>'><?php echo zget($lang->programplan->typeList, $executionType);?></span> <span class='caret'></span></a>
<ul class='dropdown-menu' style='max-height:240px; max-width: 300px; overflow-y:auto'>
<?php
foreach($lang->programplan->typeList as $key => $value)
{
$class = $executionType == $key ? 'class="active"' : '';
echo "<li $class>" . html::a($this->createLink('programplan', 'create', "projectID=$project->id&productID=$productID&planID=$planID&type=$key"), $value) . "</li>";
}
?>
</ul>
</div>
</div>
<?php endif;?>
<div class="btn-toolbar pull-right">
<?php $customLink = $this->createLink('custom', 'ajaxSaveCustomFields', 'module=programplan&section=custom&key=createFields')?>
<?php $customLink = $this->createLink('custom', 'ajaxSaveCustomFields', "module=programplan&section={$custom}&key=createFields")?>
<?php include '../../common/view/customfield.html.php';?>
</div>
</div>
<?php $hideAttribute = isset($visibleFields['attribute']) ? '' : ' hidden'?>
<?php $typeClass = ($planID != 0 and $executionType == 'agileplus') ? '' : ' hidden'?>
<?php $attrAlign = $enableOptionalAttr ? '' : 'text-center';?>
<?php $class = $planID == 0 ? '' : "disabled='disabled'"?>
<?php $name = $planID == 0 ? $lang->programplan->name : $lang->programplan->subStageName;?>
<form class='main-form form-ajax' method='post' id='planForm' enctype='multipart/form-data'>
<div class='table-responsive'>
<table class='table table-form'>
<thead>
<tr class='text-center'>
<th class='c-name required'><?php echo $name;?></th>
<th class='c-type<?php echo $typeClass;?> required'><?php echo $lang->execution->method;?></th>
<th class='c-name required'><?php echo $executionType == 'stage' ? $name : $lang->nameAB;?></th>
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
<th class='c-code required'><?php echo $lang->execution->code;?></th>
<th class='c-code required'><?php echo $executionType == 'stage' ? $lang->execution->code : $lang->code;?></th>
<?php endif;?>
<th class='c-pm <?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>'><?php echo $lang->programplan->PM;?></th>
<th class='c-pm <?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>'><?php echo $executionType == 'stage' ? $lang->programplan->PM : $lang->programplan->PMAB;?></th>
<th class='c-percent <?php echo zget($visibleFields, 'percent', ' hidden') . zget($requiredFields, 'percent', '', ' required');?>'>
<?php echo $lang->programplan->percent;?>
<?php if($planID):?>
@@ -75,7 +93,8 @@
<th class='c-date required'><?php echo $lang->programplan->end;?></th>
<th class='c-date <?php echo zget($visibleFields, 'realBegan', ' hidden') . zget($requiredFields, 'realBegan', '', ' required');?>'><?php echo $lang->programplan->realBegan;?></th>
<th class='c-date <?php echo zget($visibleFields, 'realEnd', ' hidden') . zget($requiredFields, 'realEnd', '', ' required');?>'><?php echo $lang->programplan->realEnd;?></th>
<?php if($this->config->edition == 'max'):?>
<th class='c-desc <?php echo zget($visibleFields, 'desc', ' hidden') . zget($requiredFields, 'desc', '', ' required');?>'><?php echo $lang->programplan->desc;?></th>
<?php if($this->config->edition == 'max' and $executionType == 'stage'):?>
<th class='w-110px'><?php echo $lang->programplan->output;?></th>
<?php endif;?>
<th class="c-action text-center w-110px"> <?php echo $lang->actions;?></th>
@@ -104,7 +123,7 @@
<td><input type='text' name='end[<?php echo $i;?>]' id='end<?php echo $i;?>' value='' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realBegan', ' hidden') . zget($requiredFields, 'realBegan', '', ' required');?>><input type='text' name='realBegan[<?php echo $i;?>]' id='realBegan<?php echo $i;?>' value='' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realEnd', ' hidden') . zget($requiredFields, 'realEnd', '', ' required');?>><input type='text' name='realEnd[<?php echo $i;?>]' id='realEnd<?php echo $i;?>' value='' class='form-control form-date' /></td>
<?php if($this->config->edition == 'max'):?>
<?php if($this->config->edition == 'max' and $executionType == 'stage'):?>
<td><?php echo html::select("output[$i][]", $documentList, '', "class='form-control picker-select' data-drop-width='auto' multiple");?></td>
<?php endif;?>
<td class='c-actions text-center'>
@@ -119,9 +138,10 @@
<?php endif;?>
<?php if(!empty($plans)):?>
<?php foreach($plans as $plan):?>
<?php $disabled = $plan->setMilestone ? '' : "disabled='disabled'"?>
<?php $disabled = isset($plan->setMilestone) ? '' : "disabled='disabled'"?>
<?php echo html::hidden("planIDList[$i]", $plan->id);?>
<tr>
<td class='<?php echo $typeClass;?>'><?php echo html::select("type[$i]", $lang->execution->typeList, $plan->type, "class='form-control chosen'");?></td>
<td><input type='text' name="names[<?php echo $i;?>]" id='names<?php echo $i;?>' value='<?php echo $plan->name;?>' class='form-control' /></td>
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
<td><?php echo html::input("codes[$i]", $plan->code, "class='form-control'");?></td>
@@ -140,7 +160,8 @@
<td><input type='text' name='end[<?php echo $i;?>]' id='end<?php echo $i;?>' value='<?php echo $plan->end;?>' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realBegan', ' hidden') . zget($requiredFields, 'realBegan', '', ' required');?>><input type='text' name='realBegan[<?php echo $i;?>] ' id='realBegan<?php echo $i;?>' value='<?php echo $plan->realBegan;?>' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realEnd', ' hidden') . zget($requiredFields, 'realEnd', '', ' required');?>><input type='text' name='realEnd[<?php echo $i;?>]' id='realEnd<?php echo $i;?>' value='<?php echo $plan->realEnd;?>' class='form-control form-date' /></td>
<?php if($this->config->edition == 'max'):?>
<td class='<?php echo zget($visibleFields, 'desc', 'hidden')?>'><?php echo html::textarea("desc[$i]", $plan->desc, "rows='1' class='form-control autosize'");?></td>
<?php if($this->config->edition == 'max' and $executionType == 'stage'):?>
<?php $option = empty($plan->output) ? 0 : explode(',', $plan->output);?>
<td><?php echo html::select("output[$i][]", $documentList, $option, "class='form-control picker-select' data-drop-width='auto' multiple");?></td>
<?php endif;?>
@@ -156,6 +177,7 @@
<?php endif;?>
<?php for($j = 0; $j < 5; $j ++):?>
<tr class='addedItem'>
<td class='<?php echo $typeClass;?>'><?php echo html::select("type[$i]", $lang->execution->typeList, '', "class='form-control chosen'");?></td>
<td><input type='text' name='names[<?php echo $i;?>]' id='names<?php echo $i;?>' value='' class='form-control' /></td>
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
<td><?php echo html::input("codes[$i]", '', "class='form-control'");?></td>
@@ -167,14 +189,15 @@
<span class='input-group-addon'>%</span>
</div>
</td>
<td class='<?php echo $hideAttribute . zget($requiredFields, 'attribute', '', ' required');?> <?php echo $attrAlign;?>'><?php echo html::select("attributes[$i]", $lang->stage->typeList, '', "class='form-control'");?></td>
<td class='<?php echo $hideAttribute . zget($requiredFields, 'attribute', '', ' required');?> <?php echo $attrAlign;?>'><?php echo $enableOptionalAttr ? html::select("attributes[$i]", $lang->stage->typeList, '', "class='form-control'") : zget($lang->stage->typeList, $programPlan->attribute);?></td>
<td <?php echo zget($visibleFields, 'acl', ' hidden') . zget($requiredFields, 'acl', '', ' required');?>><?php echo html::select("acl[$i]", $lang->execution->aclList, empty($programPlan) ? 'open' : $programPlan->acl, "class='form-control' $class");?></td>
<td class='text-center' <?php echo zget($visibleFields, 'milestone', ' hidden') . zget($requiredFields, 'milestone', '', ' required');?>><?php echo html::radio("milestone[$i]", $lang->programplan->milestoneList, 0);?></td>
<td><input type='text' name='begin[<?php echo $i;?>] ' id='begin<?php echo $i;?>' value='' class='form-control form-date' /></td>
<td><input type='text' name='end[<?php echo $i;?>]' id='end<?php echo $i;?>' value='' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realBegan', ' hidden') . zget($requiredFields, 'realBegan', '', ' required');?>><input type='text' name='realBegan[<?php echo $i;?>] ' id='realBegan<?php echo $i;?>' value='' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realEnd', ' hidden') . zget($requiredFields, 'realEnd', '', ' required');?>><input type='text' name='realEnd[<?php echo $i;?>]' id='realEnd<?php echo $i;?>' value='' class='form-control form-date' /></td>
<?php if($this->config->edition == 'max'):?>
<td class='<?php echo zget($visibleFields, 'desc', 'hidden')?>'><?php echo html::textarea("desc[$i]", '', "rows='1' class='form-control autosize'");?></td>
<?php if($this->config->edition == 'max' and $executionType == 'stage'):?>
<td><?php echo html::select("output[$i][]", $documentList, '', "class='form-control picker-select' data-drop-width='auto' multiple");?></td>
<?php endif;?>
<td class='c-actions text-center'>
@@ -201,6 +224,7 @@
<?php $i = '%i%';?>
<table class='hidden'>
<tr id='addItem' class='hidden'>
<td class='<?php echo $typeClass;?>'><?php echo html::select("type[$i]", $lang->execution->typeList, '', "class='form-control chosen'");?></td>
<td><input type='text' name='<?php echo "names[$i]";?>' id='names<?php echo $i;?>' class='form-control' /></td>
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
<td><?php echo html::input("codes[$i]", '', "class='form-control'");?></td>
@@ -213,14 +237,15 @@
<span class='input-group-addon'>%</span>
</div>
</td>
<td class='<?php echo $hideAttribute . zget($requiredFields, 'attribute', '', ' required');?> <?php echo $attrAlign;?>'><?php echo html::select("attributes[$i]", $lang->stage->typeList, '', "class='form-control'");?></td>
<td class='<?php echo $hideAttribute . zget($requiredFields, 'attribute', '', ' required');?> <?php echo $attrAlign;?>'><?php echo $enableOptionalAttr ? html::select("attributes[$i]", $lang->stage->typeList, '', "class='form-control'") : zget($lang->stage->typeList, $programPlan->attribute);?></td>
<td <?php echo zget($visibleFields, 'acl', ' hidden') . zget($requiredFields, 'acl', '', ' required');?>><?php echo html::select("acl[$i]", $lang->execution->aclList, empty($programPlan) ? 'open' : $programPlan->acl, "class='form-control' $class");?></td>
<td class='text-center' <?php echo zget($visibleFields, 'milestone', ' hidden') . zget($requiredFields, 'milestone', '', ' required');?>><?php echo html::radio("milestone[$i]", $lang->programplan->milestoneList, 0);?></td>
<td><input type='text' name='<?php echo "begin[$i]";?>' id='begin<?php echo $i;?>' class='form-control form-date' /></td>
<td><input type='text' name='<?php echo "end[$i]";?>' id='end<?php echo $i;?>' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realBegan', ' hidden') . zget($requiredFields, 'realBegan', '', ' required');?>><input type='text' name='<?php echo "realBegan[$i]";?>' id='realBegan<?php echo $i;?>' class='form-control form-date' /></td>
<td <?php echo zget($visibleFields, 'realEnd', ' hidden') . zget($requiredFields, 'realEnd', '', ' required');?>><input type='text' name='<?php echo "realEnd[$i]";?>' id='realEnd<?php echo $i;?>' class='form-control form-date' /></td>
<?php if($this->config->edition == 'max'):?>
<td class='<?php echo zget($visibleFields, 'desc', 'hidden')?>'><?php echo html::textarea("desc[$i]", '', "rows='1' class='form-control autosize'");?></td>
<?php if($this->config->edition == 'max' and $executionType == 'stage'):?>
<td><?php echo html::select("output[$i][]", $documentList, '', "class='form-control' data-drop-width='auto' multiple");?></td>
<?php endif;?>
<td class='c-actions text-center'>