mirror of
https://github.com/VTECRM/vtenext.git
synced 2026-02-26 16:18:47 +00:00
465 lines
19 KiB
PHP
465 lines
19 KiB
PHP
<?php
|
|
/*************************************
|
|
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
************************************/
|
|
|
|
class ProjectPlan extends CRMEntity {
|
|
var $db, $log; // Used in class functions of CRMEntity
|
|
|
|
var $table_name;
|
|
var $table_index= 'projectid';
|
|
var $column_fields = Array();
|
|
|
|
/** Indicator if this is a custom module or standard module */
|
|
var $IsCustomModule = true;
|
|
|
|
/**
|
|
* Mandatory table for supporting custom fields.
|
|
*/
|
|
var $customFieldTable = Array();
|
|
|
|
/**
|
|
* Mandatory for Saving, Include tables related to this module.
|
|
*/
|
|
var $tab_name = Array();
|
|
|
|
/**
|
|
* Mandatory for Saving, Include tablename and tablekey columnname here.
|
|
*/
|
|
var $tab_name_index = Array();
|
|
|
|
/**
|
|
* Mandatory for Listing (Related listview)
|
|
*/
|
|
var $list_fields = Array (
|
|
/* Format: Field Label => Array(tablename, columnname) */
|
|
// tablename should not have prefix 'vte_'
|
|
'Project No'=> Array('project', 'project_no'),
|
|
'Project Name'=> Array('project', 'projectname'),
|
|
'Start Date'=> Array('project', 'startdate'),
|
|
'Status'=>Array('project','projectstatus'),
|
|
'Type'=>Array('project','projecttype'),
|
|
'Assigned To' => Array('crmentity','smownerid')
|
|
);
|
|
var $list_fields_name = Array(
|
|
/* Format: Field Label => fieldname */
|
|
'Project No'=> 'project_no',
|
|
'Project Name'=> 'projectname',
|
|
'Start Date'=> 'startdate',
|
|
'Status'=>'projectstatus',
|
|
'Type'=>'projecttype',
|
|
'Assigned To' => 'assigned_user_id'
|
|
);
|
|
|
|
// Make the field link to detail view from list view (Fieldname)
|
|
var $list_link_field = 'projectname';
|
|
|
|
// For Popup listview and UI type support
|
|
var $search_fields = Array(
|
|
/* Format: Field Label => Array(tablename, columnname) */
|
|
// tablename should not have prefix 'vte_'
|
|
'Project Name'=> Array('project', 'projectname'),
|
|
'Start Date'=> Array('project', 'startdate'),
|
|
'Status'=>Array('project','projectstatus'),
|
|
'Type'=>Array('project','projecttype'),
|
|
);
|
|
var $search_fields_name = Array(
|
|
/* Format: Field Label => fieldname */
|
|
'Project Name'=> 'projectname',
|
|
'Start Date'=> 'startdate',
|
|
'Status'=>'projectstatus',
|
|
'Type'=>'projecttype',
|
|
);
|
|
|
|
// For Popup window record selection
|
|
var $popup_fields = Array('projectname');
|
|
|
|
// Placeholder for sort fields - All the fields will be initialized for Sorting through initSortFields
|
|
var $sortby_fields = Array();
|
|
|
|
// For Alphabetical search
|
|
var $def_basicsearch_col = 'projectname';
|
|
|
|
// Column value to use on detail view record text display
|
|
var $def_detailview_recname = 'projectname';
|
|
|
|
// Required Information for enabling Import feature
|
|
var $required_fields = Array('projectname'=>1);
|
|
|
|
var $default_order_by = 'projectname';
|
|
var $default_sort_order='ASC';
|
|
// Used when enabling/disabling the mandatory fields for the module.
|
|
// Refers to vte_field.fieldname values.
|
|
var $mandatory_fields = Array('assigned_user_id', 'createdtime', 'modifiedtime', 'projectname'); // crmv@177975
|
|
|
|
//crmv@10759
|
|
var $search_base_field = 'projectname';
|
|
//crmv@10759 e
|
|
|
|
function __construct() {
|
|
global $log;
|
|
global $table_prefix;
|
|
parent::__construct(); // crmv@37004
|
|
$this->table_name = $table_prefix.'_project';
|
|
$this->customFieldTable = Array($table_prefix.'_projectcf', 'projectid');
|
|
$this->tab_name = Array($table_prefix.'_crmentity', $table_prefix.'_project', $table_prefix.'_projectcf');
|
|
$this->tab_name_index = Array(
|
|
$table_prefix.'_crmentity' => 'crmid',
|
|
$table_prefix.'_project' => 'projectid',
|
|
$table_prefix.'_projectcf' => 'projectid');
|
|
$this->column_fields = getColumnFields(get_class()); //crmv@146187
|
|
$this->db = PearDatabase::getInstance();
|
|
$this->log = $log;
|
|
}
|
|
|
|
function save_module($module) {
|
|
}
|
|
|
|
/**
|
|
* Return query to use based on given modulename, fieldname
|
|
* Useful to handle specific case handling for Popup
|
|
*/
|
|
function getQueryByModuleField($module, $fieldname, $srcrecord) {
|
|
// $srcrecord could be empty
|
|
}
|
|
|
|
/**
|
|
* Invoked when special actions are performed on the module.
|
|
* @param String Module name
|
|
* @param String Event Type (module.postinstall, module.disabled, module.enabled, module.preuninstall)
|
|
*/
|
|
function vtlib_handler($modulename, $event_type) {
|
|
if($event_type == 'module.postinstall') {
|
|
global $adb;
|
|
global $table_prefix;
|
|
include_once('vtlib/Vtecrm/Module.php');//crmv@207871
|
|
$moduleInstance = Vtecrm_Module::getInstance($modulename);
|
|
$projectTabid = $moduleInstance->id;
|
|
|
|
// Mark the module as Standard module
|
|
$adb->pquery('UPDATE '.$table_prefix.'_tab SET customized=0 WHERE name=?', array($modulename));
|
|
|
|
// Add Project module to the related list of Accounts module
|
|
$accountsModuleInstance = Vtecrm_Module::getInstance('Accounts');
|
|
$accountsModuleInstance->setRelatedList($moduleInstance, 'Project Plans', Array('ADD','SELECT'), 'get_dependents_list');
|
|
|
|
// Add Project module to the related list of Contacts module
|
|
$contactsModuleInstance = Vtecrm_Module::getInstance('Contacts');
|
|
$contactsModuleInstance->setRelatedList($moduleInstance, 'Project Plans', Array('ADD','SELECT'), 'get_dependents_list');
|
|
|
|
// Add Project module to the related list of Vendors module
|
|
$vendorsModuleInstance = Vtecrm_Module::getInstance('Vendors');
|
|
$vendorsModuleInstance->setRelatedList($moduleInstance, 'ProjectPlan', array('ADD'), 'get_dependents_list');
|
|
|
|
$modcommentsModuleInstance = Vtecrm_Module::getInstance('ModComments');
|
|
if($modcommentsModuleInstance) {
|
|
include_once 'modules/ModComments/ModComments.php';
|
|
if(class_exists('ModComments')) ModComments::addWidgetTo(array('ProjectPlan'));
|
|
}
|
|
|
|
//crmv@manuele
|
|
$adb->query("INSERT INTO ".$table_prefix."_parenttab VALUES (9,'ProjectPlan',9,0,0)");
|
|
|
|
require_once('vtlib/Vtecrm/Menu.php');//crmv@207871
|
|
$menu = Vtecrm_Menu::getInstance('ProjectPlan');
|
|
$menu->addModule(Vtecrm_Module::getInstance('ProjectMilestone'));
|
|
$menu->addModule(Vtecrm_Module::getInstance('ProjectTask'));
|
|
$menu->addModule($moduleInstance);
|
|
|
|
$menu = Vtecrm_Menu::getInstance('Support');
|
|
$menu->removeModule(Vtecrm_Module::getInstance('ProjectMilestone'));
|
|
$menu->removeModule(Vtecrm_Module::getInstance('ProjectTask'));
|
|
$menu->removeModule($moduleInstance);
|
|
|
|
create_tab_data_file();
|
|
//crmv@manuele-e
|
|
|
|
//crmv@18829
|
|
$docModuleInstance = Vtecrm_Module::getInstance('Documents');
|
|
$docModuleInstance->setRelatedList($moduleInstance,'Project Plans',array('select','add'),'get_documents_dependents_list');
|
|
//crmv@18829e
|
|
|
|
//crmv@29506
|
|
$HelpDeskModuleInstance = Vtecrm_Module::getInstance('HelpDesk');
|
|
$moduleInstance->setRelatedList($HelpDeskModuleInstance,'HelpDesk',array('add'),'get_dependents_list'); //crmv@150309
|
|
//crmv@29506e
|
|
|
|
// crmv@201101
|
|
$joModuleInstance = Vtecrm_Module::getInstance('JobOrder');
|
|
$result = $adb->pquery("select * from {$table_prefix}_relatedlists where tabid = ? and related_tabid = ?", array($joModuleInstance->id,$moduleInstance->id));
|
|
if ($adb->num_rows($result) == 0) {
|
|
$joModuleInstance->setRelatedList($moduleInstance,'Project Plans',array('add','select'),'get_dependents_list');
|
|
}
|
|
// crmv@201101e
|
|
|
|
} else if($event_type == 'module.disabled') {
|
|
// TODO Handle actions when this module is disabled.
|
|
} else if($event_type == 'module.enabled') {
|
|
// TODO Handle actions when this module is enabled.
|
|
} else if($event_type == 'module.preuninstall') {
|
|
// TODO Handle actions when this module is about to be deleted.
|
|
} else if($event_type == 'module.preupdate') {
|
|
// TODO Handle actions before this module is updated.
|
|
} else if($event_type == 'module.postupdate') {
|
|
// TODO Handle actions after this module is updated.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Here we override the parent's method,
|
|
* This is done because the related lists for this module use a custom query
|
|
* that queries the child module's table (column of the uitype10 field)
|
|
*
|
|
* @see data/CRMEntity#save_related_module($module, $crmid, $with_module, $with_crmid)
|
|
*/
|
|
function save_related_module($module, $crmid, $with_module, $with_crmid, $skip_check=false) { // crmv@146653
|
|
if (!in_array($with_module, array('ProjectMilestone', 'ProjectTask'))) {
|
|
parent::save_related_module($module, $crmid, $with_module, $with_crmid, $skip_check); // crmv@146653
|
|
return;
|
|
}
|
|
/**
|
|
* $_REQUEST['action']=='Save' when choosing ADD from Related list.
|
|
* Do nothing on the project's entity when creating a related new child using ADD in relatedlist
|
|
* by doing nothing we do not insert any line in the crmentity's table when
|
|
* we are relating a module to this module
|
|
*/
|
|
if ($_REQUEST['action'] != 'updateRelations') {
|
|
return;
|
|
}
|
|
//update the child elements' column value for uitype10
|
|
$destinationModule = vtlib_purify($_REQUEST['destination_module']);
|
|
if (!is_array($with_crmid)) $with_crmid = Array($with_crmid);
|
|
foreach($with_crmid as $relcrmid) {
|
|
$child = CRMEntity::getInstance($destinationModule);
|
|
$child->retrieve_entity_info_no_html($relcrmid, $destinationModule); // crmv@188369
|
|
$child->mode='edit';
|
|
$child->column_fields['projectid']=$crmid;
|
|
//crmv@17662
|
|
$child->id = $relcrmid;
|
|
$child->save($destinationModule);
|
|
//crmv@17662e
|
|
//crmv@29617
|
|
$obj = ModNotifications::getInstance(); // crmv@164122
|
|
$obj->saveRelatedModuleNotification($crmid, $module, $relcrmid, $with_module);
|
|
//crmv@29617e
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Here we override the parent's method
|
|
* This is done because the related lists for this module use a custom query
|
|
* that queries the child module's table (column of the uitype10 field)
|
|
*
|
|
* @see data/CRMEntity#delete_related_module($module, $crmid, $with_module, $with_crmid)
|
|
*/
|
|
function delete_related_module($module, $crmid, $with_module, $with_crmid, $reverse = true) { // crmv@146653
|
|
if (!in_array($with_module, array('ProjectMilestone', 'ProjectTask', 'HelpDesk'))) { //crmv@29506
|
|
parent::delete_related_module($module, $crmid, $with_module, $with_crmid, $reverse); // crmv@146653
|
|
return;
|
|
}
|
|
$destinationModule = vtlib_purify($_REQUEST['destination_module']);
|
|
if (!is_array($with_crmid)) $with_crmid = Array($with_crmid);
|
|
foreach($with_crmid as $relcrmid) {
|
|
$child = CRMEntity::getInstance($destinationModule);
|
|
$child->retrieve_entity_info($relcrmid, $destinationModule);
|
|
$child->mode='edit';
|
|
//crmv@29506
|
|
if ($with_module == 'HelpDesk')
|
|
$child->column_fields['projectplanid']='';
|
|
else
|
|
//crmv@29506
|
|
$child->column_fields['projectid']='';
|
|
//crmv@17662
|
|
$child->id = $relcrmid;
|
|
$child->save($destinationModule);
|
|
//crmv@17662e
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle getting related list information.
|
|
* NOTE: This function has been added to CRMEntity (base class).
|
|
* You can override the behavior by re-defining it here.
|
|
*/
|
|
//function get_related_list($id, $cur_tab_id, $rel_tab_id, $actions=false) { }
|
|
|
|
/**
|
|
* Handle getting dependents list information.
|
|
* NOTE: This function has been added to CRMEntity (base class).
|
|
* You can override the behavior by re-defining it here.
|
|
*/
|
|
//function get_dependents_list($id, $cur_tab_id, $rel_tab_id, $actions=false) { }
|
|
|
|
//crmv@104562
|
|
function getExtraDetailTabs() {
|
|
global $app_strings;
|
|
|
|
$return = array(
|
|
array('label'=>getTranslatedString('LBL_PROGRESS_CHART'),'href'=>'','onclick'=>"changeDetailTab('{$this->modulename}', '{$this->id}', 'Gantt', this)")
|
|
);
|
|
$others = parent::getExtraDetailTabs() ?: array();
|
|
|
|
return array_merge($return, $others);
|
|
}
|
|
function getExtraDetailBlock($selectionProcesses=false) {
|
|
global $mod_strings, $app_strings;
|
|
require_once('include/utils/EntityColorUtils.php');
|
|
$smarty = new VteSmarty();
|
|
$ECU = EntityColorUtils::getInstance();
|
|
$smarty->assign('CURRENT_PATH','modules/ProjectPlan/thirdparty/jQueryGantt/');
|
|
$smarty->assign('STATUS_COLORS', $ECU->getModuleColors('ProjectTask'));
|
|
$extra = parent::getExtraDetailBlock();
|
|
return $extra.$smarty->fetch('modules/ProjectPlan/GanttTab.tpl');
|
|
}
|
|
function getGanttHolidays($record) {
|
|
global $adb, $table_prefix;
|
|
$holidays = '';
|
|
$result = $adb->pquery("SELECT MIN(startdate) AS \"startdate\", MAX(enddate) AS \"enddate\"
|
|
FROM {$table_prefix}_projecttask pt
|
|
INNER JOIN {$table_prefix}_crmentity crment ON pt.projecttaskid=crment.crmid
|
|
WHERE projectid=? AND crment.deleted=0 AND pt.startdate IS NOT NULL AND pt.enddate IS NOT NULL",
|
|
array($record));
|
|
if ($result && $adb->num_rows($result) > 0) {
|
|
$startdate = $adb->query_result($result,0,'startdate');
|
|
$enddate = $adb->query_result($result,0,'enddate');
|
|
$crmv_utils = CRMVUtils::getInstance();
|
|
$holidays = $crmv_utils->getHolidays($startdate,$enddate,'jQueryGantt');
|
|
if (!empty($holidays)) $holidays = '#'.implode('#',$holidays).'#';
|
|
}
|
|
return $holidays;
|
|
}
|
|
function getGanttContent($record,$return_mode='array') {
|
|
global $adb, $table_prefix;
|
|
require_once('include/utils/EntityColorUtils.php');
|
|
$ECU = EntityColorUtils::getInstance();
|
|
|
|
$tasks = array();
|
|
$resources = array();
|
|
$roles = array();
|
|
// tasks
|
|
//crmv@145469
|
|
$result = $adb->pquery("SELECT pt.*, crment.smownerid, role.roleid, role.rolename
|
|
FROM {$table_prefix}_projecttask pt
|
|
INNER JOIN {$table_prefix}_crmentity crment ON pt.projecttaskid=crment.crmid
|
|
LEFT JOIN {$table_prefix}_user2role u2r ON u2r.userid = smownerid
|
|
LEFT JOIN {$table_prefix}_role role ON role.roleid = u2r.roleid
|
|
WHERE projectid=? AND crment.deleted=0 AND pt.startdate IS NOT NULL AND pt.enddate IS NOT NULL",
|
|
array($record)) or die("Please install the ProjectMilestone and ProjectTasks modules first.");
|
|
//crmv@145469e
|
|
//ORDER BY pt.startdate ASC, pt.enddate DESC
|
|
$resources_ids = array();
|
|
$roles_ids = array();
|
|
while($row=$adb->fetchByAssoc($result)){
|
|
$startdate = $row['startdate'];
|
|
if ($row['projecttaskprogress'] == "--none--") {
|
|
$progress = 0;
|
|
} else {
|
|
$progress = str_replace("%","",$row['projecttaskprogress']);
|
|
}
|
|
$clvColor = $ECU->getEntityColor('ProjectTask',$row['projecttaskid']);
|
|
(!empty($clvColor)) ? $status = 'COLOR_'.str_replace('#','',$clvColor) : $status = 'DEFAULT';
|
|
|
|
$assigs = array();
|
|
$tasks[] = array(
|
|
'id'=>$row['projecttaskid'],
|
|
'name'=>$row['projecttaskname'],
|
|
'code'=>$row['projecttask_no'],
|
|
'level'=>0,
|
|
'status'=>$status,
|
|
'start'=>strtotime($startdate)*1000,
|
|
'duration'=>$row['working_days'],
|
|
'end'=>strtotime($startdate)*1000 + ($row['working_days']*24*60*60),
|
|
'startIsMilestone'=>false,
|
|
'endIsMilestone'=>false,
|
|
'collapsed'=>false,
|
|
'depends'=>'',
|
|
'hasChild'=>false,
|
|
'progress'=>$progress,
|
|
'assigs'=>array(
|
|
array(
|
|
'resourceId'=>$row['smownerid'],
|
|
'id'=>$row['smownerid'],
|
|
'roleId'=>$row['roleid'],
|
|
'effort'=>0, //TODO
|
|
),
|
|
),
|
|
);
|
|
if (!in_array($row['smownerid'],$resources_ids)) {
|
|
$resources_ids[] = $row['smownerid'];
|
|
//crmv@145469
|
|
$name = getUserFullName($row['smownerid']);
|
|
if (empty($name)) {
|
|
$groupInfo = getGroupName($row['smownerid']);
|
|
$resources[] = array(
|
|
'id'=>$row['smownerid'],
|
|
'name'=>$groupInfo[0],
|
|
'img'=>getGroupAvatar(),
|
|
);
|
|
} else {
|
|
$resources[] = array(
|
|
'id'=>$row['smownerid'],
|
|
'name'=>$name,
|
|
'img'=>getUserAvatar($row['smownerid']),
|
|
);
|
|
}
|
|
//crmv@145469e
|
|
}
|
|
if (!in_array($row['roleid'],$roles_ids)) {
|
|
$roles_ids[] = $row['roleid'];
|
|
$roles[] = array(
|
|
'id'=>$row['roleid'],
|
|
'name'=>$row['rolename'],
|
|
);
|
|
}
|
|
}
|
|
// milestones
|
|
$result = $adb->pquery("SELECT pm.*, smownerid FROM {$table_prefix}_projectmilestone pm
|
|
INNER JOIN {$table_prefix}_crmentity crment on pm.projectmilestoneid=crment.crmid
|
|
WHERE projectid=? and crment.deleted=0",
|
|
array($record)) or die("Please install the ProjectMilestone and ProjectTasks modules first.");
|
|
while($row=$adb->fetchByAssoc($result)){
|
|
$tasks[] = array(
|
|
'id'=>$row['projectmilestoneid'],
|
|
'name'=>$row['projectmilestonename'],
|
|
'code'=>$row['projectmilestone_no'],
|
|
'level'=>0,
|
|
'status'=>$status,
|
|
'start'=>strtotime($row['projectmilestonedate'])*1000,
|
|
'duration'=>1,
|
|
'end'=>strtotime($row['projectmilestonedate'].' 23:59:59')*1000,
|
|
'isMilestone'=>true,
|
|
);
|
|
}
|
|
usort($tasks, function($a, $b) {
|
|
return ($a['start'] > $b['start']);
|
|
});
|
|
$return = array(
|
|
'tasks'=>$tasks,
|
|
'resources'=>$resources,
|
|
'roles'=>$roles,
|
|
'selectedRow'=>0,
|
|
'canWrite'=>false,
|
|
'canWriteOnParent'=>false,
|
|
);
|
|
if ($return_mode == 'json') {
|
|
/* ex.
|
|
{"tasks":[
|
|
{"id":100,"name":"Gantt editor","code":"","level":0,"status":"s0","start":1396994400000,"duration":21,"end":1399672799999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"hasChild":false}
|
|
,{"id":2,"name":"coding","code":"","level":0,"status":"s2","start":1396994400000,"duration":10,"end":1398203999999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"description":"","progress":0,"hasChild":false}
|
|
,{"id":32,"name":"gantt part","code":"","level":0,"status":"s3","start":1396994400000,"duration":2,"end":1397167199999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"depends":"","hasChild":false}
|
|
,{"id":45,"name":"editor part","code":"","level":0,"status":"s1","start":1397167200000,"duration":4,"end":1397685599999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"depends":"","hasChild":false}
|
|
,{"id":56,"name":"testing","code":"","level":0,"status":"s1","start":1398981600000,"duration":6,"end":1399672799999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"depends":"","description":"","progress":0,"hasChild":false}
|
|
,{"id":678,"name":"test on safari","code":"","level":0,"status":"","start":1398981600000,"duration":2,"end":1399327199999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"depends":"","hasChild":false}
|
|
,{"id":700,"name":"test on ie","code":"","level":0,"status":"STATUS_UNDEFINED","start":1399327200000,"duration":3,"end":1399586399999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"depends":"","hasChild":false}
|
|
,{"id":8365,"name":"test on chrome","code":"","level":0,"status":"s2","start":1399327200000,"duration":2,"end":1399499999999,"startIsMilestone":false,"endIsMilestone":false,"collapsed":false,"assigs":[],"depends":"","hasChild":false}
|
|
],"selectedRow":0,"canWrite":false,"canWriteOnParent":true}
|
|
*/
|
|
return Zend_Json::encode($return);
|
|
} else {
|
|
return $return;
|
|
}
|
|
}
|
|
//crmv@104562e
|
|
}
|
|
?>
|