diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/CallRelatedList.php b/oss/vtiger/trunk/modules/ProjectMilestone/CallRelatedList.php
new file mode 100644
index 00000000..9005316f
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/CallRelatedList.php
@@ -0,0 +1,80 @@
+retrieve_entity_info($record, $currentModule);
+ $focus->id = $record;
+ }
+
+ $smarty = new vtigerCRM_Smarty;
+
+ if($isduplicate == 'true') $focus->id = '';
+ if(isset($_REQUEST['mode']) && $_REQUEST['mode'] != ' ') $smarty->assign("OP_MODE",vtlib_purify($_REQUEST['mode']));
+ if(!$_SESSION['rlvs'][$currentModule]) unset($_SESSION['rlvs']);
+
+ // Identify this module as custom module.
+ $smarty->assign('CUSTOM_MODULE', true);
+
+ $smarty->assign('APP', $app_strings);
+ $smarty->assign('MOD', $mod_strings);
+ $smarty->assign('MODULE', $currentModule);
+ // TODO: Update Single Module Instance name here.
+ $smarty->assign('SINGLE_MOD', getTranslatedString('SINGLE_'.$currentModule, $currentModule));
+ $smarty->assign('CATEGORY', $category);
+ $smarty->assign('IMAGE_PATH', "themes/$theme/images/");
+ $smarty->assign('THEME', $theme);
+ $smarty->assign('ID', $focus->id);
+ $smarty->assign('MODE', $focus->mode);
+ $smarty->assign('CHECK', $tool_buttons);
+
+ $smarty->assign('NAME', $focus->column_fields[$focus->def_detailview_recname]);
+ $smarty->assign('UPDATEINFO',updateInfo($focus->id));
+
+ // Module Sequence Numbering
+ $mod_seq_field = getModuleSequenceField($currentModule);
+ if ($mod_seq_field != null) {
+ $mod_seq_id = $focus->column_fields[$mod_seq_field['name']];
+ } else {
+ $mod_seq_id = $focus->id;
+ }
+ $smarty->assign('MOD_SEQ_ID', $mod_seq_id);
+ // END
+
+ $related_array = getRelatedLists($currentModule, $focus);
+ $smarty->assign('RELATEDLISTS', $related_array);
+
+ require_once('include/ListView/RelatedListViewSession.php');
+ if(!empty($_REQUEST['selected_header']) && !empty($_REQUEST['relation_id'])) {
+ $relationId = vtlib_purify($_REQUEST['relation_id']);
+ RelatedListViewSession::addRelatedModuleToSession($relationId,
+ vtlib_purify($_REQUEST['selected_header']));
+ }
+ $open_related_modules = RelatedListViewSession::getRelatedModulesFromSession();
+ $smarty->assign("SELECTEDHEADERS", $open_related_modules);
+
+ $smarty->display('RelatedLists.tpl');
+}
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/CustomView.php b/oss/vtiger/trunk/modules/ProjectMilestone/CustomView.php
new file mode 100644
index 00000000..aebb8b53
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/CustomView.php
@@ -0,0 +1,12 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/Delete.php b/oss/vtiger/trunk/modules/ProjectMilestone/Delete.php
new file mode 100644
index 00000000..c37c3c1b
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/Delete.php
@@ -0,0 +1,27 @@
+
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/DetailView.php b/oss/vtiger/trunk/modules/ProjectMilestone/DetailView.php
new file mode 100644
index 00000000..a944883f
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/DetailView.php
@@ -0,0 +1,110 @@
+id = $record;
+ $focus->retrieve_entity_info($record, $currentModule);
+}
+if($isduplicate == 'true') $focus->id = '';
+
+// Identify this module as custom module.
+$smarty->assign('CUSTOM_MODULE', true);
+
+$smarty->assign('APP', $app_strings);
+$smarty->assign('MOD', $mod_strings);
+$smarty->assign('MODULE', $currentModule);
+// TODO: Update Single Module Instance name here.
+$smarty->assign('SINGLE_MOD', 'SINGLE_'.$currentModule);
+$smarty->assign('CATEGORY', $category);
+$smarty->assign('IMAGE_PATH', "themes/$theme/images/");
+$smarty->assign('THEME', $theme);
+$smarty->assign('ID', $focus->id);
+$smarty->assign('MODE', $focus->mode);
+
+$recordName = array_values(getEntityName($currentModule, $focus->id));
+$recordName = $recordName[0];
+$smarty->assign('NAME', $recordName);
+$smarty->assign('UPDATEINFO',updateInfo($focus->id));
+
+// Module Sequence Numbering
+$mod_seq_field = getModuleSequenceField($currentModule);
+if ($mod_seq_field != null) {
+ $mod_seq_id = $focus->column_fields[$mod_seq_field['name']];
+} else {
+ $mod_seq_id = $focus->id;
+}
+$smarty->assign('MOD_SEQ_ID', $mod_seq_id);
+// END
+
+$validationArray = split_validationdataArray(getDBValidationData($focus->tab_name, $tabid));
+$smarty->assign('VALIDATION_DATA_FIELDNAME',$validationArray['fieldname']);
+$smarty->assign('VALIDATION_DATA_FIELDDATATYPE',$validationArray['datatype']);
+$smarty->assign('VALIDATION_DATA_FIELDLABEL',$validationArray['fieldlabel']);
+
+$smarty->assign('EDIT_PERMISSION', isPermitted($currentModule, 'EditView', $record));
+$smarty->assign('CHECK', $tool_buttons);
+
+if(PerformancePrefs::getBoolean('DETAILVIEW_RECORD_NAVIGATION', true) && isset($_SESSION[$currentModule.'_listquery'])){
+ $recordNavigationInfo = ListViewSession::getListViewNavigation($focus->id);
+ VT_detailViewNavigation($smarty,$recordNavigationInfo,$focus->id);
+}
+
+$smarty->assign('IS_REL_LIST', isPresentRelatedLists($currentModule));
+$smarty->assign('SinglePane_View', $singlepane_view);
+
+if($singlepane_view == 'true') {
+ $related_array = getRelatedLists($currentModule,$focus);
+ $smarty->assign("RELATEDLISTS", $related_array);
+
+ require_once('include/ListView/RelatedListViewSession.php');
+ if(!empty($_REQUEST['selected_header']) && !empty($_REQUEST['relation_id'])) {
+ RelatedListViewSession::addRelatedModuleToSession(vtlib_purify($_REQUEST['relation_id']),
+ vtlib_purify($_REQUEST['selected_header']));
+ }
+ $open_related_modules = RelatedListViewSession::getRelatedModulesFromSession();
+ $smarty->assign("SELECTEDHEADERS", $open_related_modules);
+}
+
+if(isPermitted($currentModule, 'EditView', $record) == 'yes')
+ $smarty->assign('EDIT_DUPLICATE', 'permitted');
+if(isPermitted($currentModule, 'Delete', $record) == 'yes')
+ $smarty->assign('DELETE', 'permitted');
+
+$smarty->assign('BLOCKS', getBlocks($currentModule,'detail_view','',$focus->column_fields));
+
+// Gather the custom link information to display
+include_once('vtlib/Vtiger/Link.php');
+$customlink_params = Array('MODULE'=>$currentModule, 'RECORD'=>$focus->id, 'ACTION'=>vtlib_purify($_REQUEST['action']));
+$smarty->assign('CUSTOM_LINKS', Vtiger_Link::getAllByType(getTabid($currentModule), Array('DETAILVIEWBASIC','DETAILVIEW','DETAILVIEWWIDGET'), $customlink_params));
+// END
+
+// Record Change Notification
+$focus->markAsViewed($current_user->id);
+// END
+
+$smarty->assign('DETAILVIEW_AJAX_EDIT', PerformancePrefs::getBoolean('DETAILVIEW_AJAX_EDIT', true));
+
+$smarty->display('DetailView.tpl');
+
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/DetailViewAjax.php b/oss/vtiger/trunk/modules/ProjectMilestone/DetailViewAjax.php
new file mode 100644
index 00000000..87b466bd
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/DetailViewAjax.php
@@ -0,0 +1,41 @@
+retrieve_entity_info($crmid, $currentModule);
+ $modObj->column_fields[$fieldname] = $fieldvalue;
+ $modObj->id = $crmid;
+ $modObj->mode = 'edit';
+ $modObj->save($currentModule);
+ if($modObj->id != '')
+ {
+ echo ':#:SUCCESS';
+ }else
+ {
+ echo ':#:FAILURE';
+ }
+ }else
+ {
+ echo ':#:FAILURE';
+ }
+} elseif($ajaxaction == "LOADRELATEDLIST" || $ajaxaction == "DISABLEMODULE"){
+ require_once 'include/ListView/RelatedListViewContents.php';
+}
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/EditView.php b/oss/vtiger/trunk/modules/ProjectMilestone/EditView.php
new file mode 100644
index 00000000..3c03d614
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/EditView.php
@@ -0,0 +1,113 @@
+assign("SEARCH", $searchurl);
+//4600 ends
+
+if($record) {
+ $focus->id = $record;
+ $focus->mode = 'edit';
+ $focus->retrieve_entity_info($record, $currentModule);
+}
+if($isduplicate == 'true') {
+ $focus->id = '';
+ $focus->mode = '';
+}
+if(empty($_REQUEST['record']) && $focus->mode != 'edit'){
+ setObjectValuesFromRequest($focus);
+}
+
+$disp_view = getView($focus->mode);
+if($disp_view == 'edit_view')
+ $smarty->assign('BLOCKS', getBlocks($currentModule, $disp_view, $focus->mode, $focus->column_fields));
+else
+ $smarty->assign('BASBLOCKS', getBlocks($currentModule, $disp_view, $focus->mode, $focus->column_fields, 'BAS'));
+
+$smarty->assign('OP_MODE',$disp_view);
+$smarty->assign('APP', $app_strings);
+$smarty->assign('MOD', $mod_strings);
+$smarty->assign('MODULE', $currentModule);
+// TODO: Update Single Module Instance name here.
+$smarty->assign('SINGLE_MOD', getTranslatedString('SINGLE_'.$currentModule));
+$smarty->assign('CATEGORY', $category);
+$smarty->assign("THEME", $theme);
+$smarty->assign('IMAGE_PATH', "themes/$theme/images/");
+$smarty->assign('ID', $focus->id);
+$smarty->assign('MODE', $focus->mode);
+
+$smarty->assign('CHECK', Button_Check($currentModule));
+$smarty->assign('DUPLICATE', $isduplicate);
+
+if($focus->mode == 'edit' || $isduplicate) {
+ $recordName = array_values(getEntityName($currentModule, $record));
+ $recordName = $recordName[0];
+ $smarty->assign('NAME', $recordName);
+ $smarty->assign('UPDATEINFO',updateInfo($record));
+}
+
+if(isset($_REQUEST['return_module'])) $smarty->assign("RETURN_MODULE", vtlib_purify($_REQUEST['return_module']));
+if(isset($_REQUEST['return_action'])) $smarty->assign("RETURN_ACTION", vtlib_purify($_REQUEST['return_action']));
+if(isset($_REQUEST['return_id'])) $smarty->assign("RETURN_ID", vtlib_purify($_REQUEST['return_id']));
+if (isset($_REQUEST['return_viewname'])) $smarty->assign("RETURN_VIEWNAME", vtlib_purify($_REQUEST['return_viewname']));
+
+// Field Validation Information
+$tabid = getTabid($currentModule);
+$validationData = getDBValidationData($focus->tab_name,$tabid);
+$validationArray = split_validationdataArray($validationData);
+
+$smarty->assign("VALIDATION_DATA_FIELDNAME",$validationArray['fieldname']);
+$smarty->assign("VALIDATION_DATA_FIELDDATATYPE",$validationArray['datatype']);
+$smarty->assign("VALIDATION_DATA_FIELDLABEL",$validationArray['fieldlabel']);
+
+// In case you have a date field
+$smarty->assign("CALENDAR_LANG", $app_strings['LBL_JSCALENDAR_LANG']);
+
+global $adb;
+// Module Sequence Numbering
+$mod_seq_field = getModuleSequenceField($currentModule);
+if($focus->mode != 'edit' && $mod_seq_field != null) {
+ $autostr = getTranslatedString('MSG_AUTO_GEN_ON_SAVE');
+ $mod_seq_string = $adb->pquery("SELECT prefix, cur_id from vtiger_modentity_num where semodule = ? and active=1",array($currentModule));
+ $mod_seq_prefix = $adb->query_result($mod_seq_string,0,'prefix');
+ $mod_seq_no = $adb->query_result($mod_seq_string,0,'cur_id');
+ if($adb->num_rows($mod_seq_string) == 0 || $focus->checkModuleSeqNumber($focus->table_name, $mod_seq_field['column'], $mod_seq_prefix.$mod_seq_no))
+ echo '
'. getTranslatedString('LBL_DUPLICATE'). ' '. getTranslatedString($mod_seq_field['label'])
+ .' - '. getTranslatedString('LBL_CLICK') .' '.getTranslatedString('LBL_HERE').' '
+ . getTranslatedString('LBL_TO_CONFIGURE'). ' '. getTranslatedString($mod_seq_field['label']) .'';
+ else
+ $smarty->assign("MOD_SEQ_ID",$autostr);
+} else {
+ $smarty->assign("MOD_SEQ_ID", $focus->column_fields[$mod_seq_field['name']]);
+}
+// END
+
+// Gather the help information associated with fields
+$smarty->assign('FIELDHELPINFO', vtlib_getFieldHelpInfo($currentModule));
+// END
+
+if($focus->mode == 'edit') {
+ $smarty->display('salesEditView.tpl');
+} else {
+ $smarty->display('CreateView.tpl');
+}
+
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/ExportRecords.php b/oss/vtiger/trunk/modules/ProjectMilestone/ExportRecords.php
new file mode 100644
index 00000000..31029bc0
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/ExportRecords.php
@@ -0,0 +1,12 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/FindDuplicateRecords.php b/oss/vtiger/trunk/modules/ProjectMilestone/FindDuplicateRecords.php
new file mode 100644
index 00000000..b1a36b7b
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/FindDuplicateRecords.php
@@ -0,0 +1,106 @@
+pquery($sql, array($id));
+ DeleteEntity($req_module,$return_module,$focus,$id,"");
+ }
+ else {
+ $ids_list[] = $id;
+ }
+}
+ if(count($ids_list) > 0) {
+ $ret = getEntityName($req_module,$ids_list);
+ if(count($ret) > 0)
+ {
+ $errormsg = implode(',',$ret);
+ }
+ echo "
";
+ exit;
+ }
+}
+
+include("include/saveMergeCriteria.php");
+$ret_arr=getDuplicateRecordsArr($req_module);
+
+$fld_values=$ret_arr[0];
+$total_num_group=count($fld_values);
+$fld_name=$ret_arr[1];
+$ui_type=$ret_arr[2];
+
+$smarty->assign("NAVIGATION",$ret_arr["navigation"]);//Added for page navigation
+$smarty->assign("MODULE",$req_module);
+$smarty->assign("NUM_GROUP",$total_num_group);
+$smarty->assign("FIELD_NAMES",$fld_name);
+$smarty->assign("CATEGORY",$parenttab);
+$smarty->assign("ALL_VALUES",$fld_values);
+if(isPermitted($req_module,'Delete','') == 'yes')
+ $button_del = $app_strings['LBL_MASS_DELETE'];
+$smarty->assign("DELETE",$button_del);
+
+$smarty->assign("MOD", return_module_language($current_language,$req_module));
+$smarty->assign("THEME", $theme);
+$smarty->assign("IMAGE_PATH",$image_path);
+$smarty->assign("APP", $app_strings);
+$smarty->assign("CMOD", $mod_strings);
+$smarty->assign("MODE",'view');
+if(isset($_REQUEST['button_view']))
+{
+ $smarty->assign("VIEW",'true');
+}
+if(isset($_REQUEST['ajax']) && $_REQUEST['ajax'] != '')
+ $smarty->display("FindDuplicateAjax.tpl");
+else
+ $smarty->display('FindDuplicateDisplay.tpl');
+
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/Import.php b/oss/vtiger/trunk/modules/ProjectMilestone/Import.php
new file mode 100644
index 00000000..576068f5
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/Import.php
@@ -0,0 +1,12 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/ListView.php b/oss/vtiger/trunk/modules/ProjectMilestone/ListView.php
new file mode 100644
index 00000000..72359033
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/ListView.php
@@ -0,0 +1,213 @@
+initSortbyField($currentModule);
+$sorder = $focus->getSortOrder();
+$order_by = $focus->getOrderBy();
+
+$_SESSION[$currentModule."_Order_By"] = $order_by;
+$_SESSION[$currentModule."_Sort_Order"]=$sorder;
+
+$smarty = new vtigerCRM_Smarty();
+
+// Identify this module as custom module.
+$smarty->assign('CUSTOM_MODULE', true);
+
+$smarty->assign('MOD', $mod_strings);
+$smarty->assign('APP', $app_strings);
+$smarty->assign('MODULE', $currentModule);
+$smarty->assign('SINGLE_MOD', getTranslatedString('SINGLE_'.$currentModule));
+$smarty->assign('CATEGORY', $category);
+$smarty->assign('BUTTONS', $list_buttons);
+$smarty->assign('CHECK', $tool_buttons);
+$smarty->assign('THEME', $theme);
+$smarty->assign('IMAGE_PATH', "themes/$theme/images/");
+
+$smarty->assign('CHANGE_OWNER', getUserslist());
+$smarty->assign('CHANGE_GROUP_OWNER', getGroupslist());
+
+// Custom View
+$customView = new CustomView($currentModule);
+$viewid = $customView->getViewId($currentModule);
+$customview_html = $customView->getCustomViewCombo($viewid);
+$viewinfo = $customView->getCustomViewByCvid($viewid);
+
+// Feature available from 5.1
+if(method_exists($customView, 'isPermittedChangeStatus')) {
+ // Approving or Denying status-public by the admin in CustomView
+ $statusdetails = $customView->isPermittedChangeStatus($viewinfo['status']);
+
+ // To check if a user is able to edit/delete a CustomView
+ $edit_permit = $customView->isPermittedCustomView($viewid,'EditView',$currentModule);
+ $delete_permit = $customView->isPermittedCustomView($viewid,'Delete',$currentModule);
+
+ $smarty->assign("CUSTOMVIEW_PERMISSION",$statusdetails);
+ $smarty->assign("CV_EDIT_PERMIT",$edit_permit);
+ $smarty->assign("CV_DELETE_PERMIT",$delete_permit);
+}
+// END
+
+$smarty->assign("VIEWID", $viewid);
+
+if($viewinfo['viewname'] == 'All') $smarty->assign('ALL', 'All');
+
+if($viewid ==0)
+{
+ echo "";
+ exit;
+}
+
+global $current_user;
+$queryGenerator = new QueryGenerator($currentModule, $current_user);
+if ($viewid != "0") {
+ $queryGenerator->initForCustomViewById($viewid);
+} else {
+ $queryGenerator->initForDefaultCustomView();
+}
+
+// Enabling Module Search
+$url_string = '';
+if($_REQUEST['query'] == 'true') {
+ $queryGenerator->addUserSearchConditions($_REQUEST);
+ $ustring = getSearchURL($_REQUEST);
+ $url_string .= "&query=true$ustring";
+ $smarty->assign('SEARCH_URL', $url_string);
+}
+
+$list_query = $queryGenerator->getQuery();
+$where = $queryGenerator->getConditionalWhere();
+if(isset($where) && $where != '') {
+ $_SESSION['export_where'] = $where;
+} else {
+ unset($_SESSION['export_where']);
+}
+
+// Sorting
+if(!empty($order_by)) {
+ if($order_by == 'smownerid') $list_query .= ' ORDER BY user_name '.$sorder;
+ else {
+ $tablename = getTableNameForField($currentModule, $order_by);
+ $tablename = ($tablename != '')? ($tablename . '.') : '';
+ $list_query .= ' ORDER BY ' . $tablename . $order_by . ' ' . $sorder;
+ }
+}
+
+//Postgres 8 fixes
+if( $adb->dbType == "pgsql")
+ $list_query = fixPostgresQuery( $list_query, $log, 0);
+
+if(PerformancePrefs::getBoolean('LISTVIEW_COMPUTE_PAGE_COUNT', false) === true){
+ $count_result = $adb->query( mkCountQuery( $list_query));
+ $noofrows = $adb->query_result($count_result,0,"count");
+}else{
+ $noofrows = null;
+}
+
+$queryMode = (isset($_REQUEST['query']) && $_REQUEST['query'] == 'true');
+$start = ListViewSession::getRequestCurrentPage($currentModule, $list_query, $viewid, $queryMode);
+
+$navigation_array = VT_getSimpleNavigationValues($start,$list_max_entries_per_page,$noofrows);
+
+$limit_start_rec = ($start-1) * $list_max_entries_per_page;
+
+if( $adb->dbType == "pgsql")
+ $list_result = $adb->pquery($list_query. " OFFSET $limit_start_rec LIMIT $list_max_entries_per_page", array());
+else
+ $list_result = $adb->pquery($list_query. " LIMIT $limit_start_rec, $list_max_entries_per_page", array());
+
+$recordListRangeMsg = getRecordRangeMessage($list_result, $limit_start_rec,$noofrows);
+$smarty->assign('recordListRange',$recordListRangeMsg);
+
+$smarty->assign("CUSTOMVIEW_OPTION",$customview_html);
+
+// Navigation
+$navigationOutput = getTableHeaderSimpleNavigation($navigation_array, $url_string, $currentModule, 'index', $viewid);
+$smarty->assign("NAVIGATION", $navigationOutput);
+
+$controller = new ListViewController($adb, $current_user, $queryGenerator);
+$listview_header = $controller->getListViewHeader($focus,$currentModule,$url_string,$sorder,
+ $order_by);
+$listview_entries = $controller->getListViewEntries($focus,$currentModule,$list_result,
+ $navigation_array);
+$listview_header_search = $controller->getBasicSearchFieldInfoList();
+
+$smarty->assign('LISTHEADER', $listview_header);
+$smarty->assign('LISTENTITY', $listview_entries);
+$smarty->assign('SEARCHLISTHEADER',$listview_header_search);
+
+// Module Search
+$alphabetical = AlphabeticalSearch($currentModule,'index',$focus->def_basicsearch_col,'true','basic','','','','',$viewid);
+$fieldnames = $controller->getAdvancedSearchOptionString();
+$criteria = getcriteria_options();
+$smarty->assign("ALPHABETICAL", $alphabetical);
+$smarty->assign("FIELDNAMES", $fieldnames);
+$smarty->assign("CRITERIA", $criteria);
+
+$smarty->assign("AVALABLE_FIELDS", getMergeFields($currentModule,"available_fields"));
+$smarty->assign("FIELDS_TO_MERGE", getMergeFields($currentModule,"fileds_to_merge"));
+
+//Added to select Multiple records in multiple pages
+$smarty->assign("SELECTEDIDS", vtlib_purify($_REQUEST['selobjs']));
+$smarty->assign("ALLSELECTEDIDS", vtlib_purify($_REQUEST['allselobjs']));
+$smarty->assign("CURRENT_PAGE_BOXES", implode(array_keys($listview_entries),";"));
+ListViewSession::setSessionQuery($currentModule,$list_query,$viewid);
+
+// Gather the custom link information to display
+include_once('vtlib/Vtiger/Link.php');
+$customlink_params = Array('MODULE'=>$currentModule, 'ACTION'=>vtlib_purify($_REQUEST['action']), 'CATEGORY'=> $category);
+$smarty->assign('CUSTOM_LINKS', Vtiger_Link::getAllByType(getTabid($currentModule), Array('LISTVIEWBASIC','LISTVIEW'), $customlink_params));
+// END
+
+if(isset($_REQUEST['ajax']) && $_REQUEST['ajax'] != '')
+ $smarty->display("ListViewEntries.tpl");
+else
+ $smarty->display('ListView.tpl');
+
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/ListViewPagging.php b/oss/vtiger/trunk/modules/ProjectMilestone/ListViewPagging.php
new file mode 100644
index 00000000..333f1768
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/ListViewPagging.php
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/MassEdit.php b/oss/vtiger/trunk/modules/ProjectMilestone/MassEdit.php
new file mode 100644
index 00000000..a48f6146
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/MassEdit.php
@@ -0,0 +1,44 @@
+mode = '';
+$mode = 'mass_edit';
+
+$disp_view = getView($focus->mode);
+$idstring = $_REQUEST['idstring'];
+
+$smarty = new vtigerCRM_Smarty;
+$smarty->assign('MODULE',$currentModule);
+$smarty->assign('APP',$app_strings);
+$smarty->assign('THEME', $theme);
+$smarty->assign('IMAGE_PATH', "themes/$theme/images/");
+$smarty->assign('IDS',$idstring);
+$smarty->assign('MASS_EDIT','1');
+$smarty->assign('BLOCKS',getBlocks($currentModule,$disp_view,$mode,$focus->column_fields));
+$smarty->assign("CATEGORY",getParentTab());
+
+// Field Validation Information
+$tabid = getTabid($currentModule);
+$validationData = getDBValidationData($focus->tab_name,$tabid);
+$validationArray = split_validationdataArray($validationData);
+
+$smarty->assign("VALIDATION_DATA_FIELDNAME",$validationArray['fieldname']);
+$smarty->assign("VALIDATION_DATA_FIELDDATATYPE",$validationArray['datatype']);
+$smarty->assign("VALIDATION_DATA_FIELDLABEL",$validationArray['fieldlabel']);
+
+$smarty->display('MassEditForm.tpl');
+
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/MassEditSave.php b/oss/vtiger/trunk/modules/ProjectMilestone/MassEditSave.php
new file mode 100644
index 00000000..0c1aa37e
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/MassEditSave.php
@@ -0,0 +1,65 @@
+retrieve_entity_info($recordid, $currentModule);
+ $focus->mode = 'edit';
+ $focus->id = $recordid;
+ foreach($focus->column_fields as $fieldname => $val)
+ {
+ if(isset($_REQUEST[$fieldname."_mass_edit_check"])) {
+ if($fieldname == 'assigned_user_id'){
+ if($_REQUEST['assigntype'] == 'U') {
+ $value = $_REQUEST['assigned_user_id'];
+ } elseif($_REQUEST['assigntype'] == 'T') {
+ $value = $_REQUEST['assigned_group_id'];
+ }
+ } else {
+ if(is_array($_REQUEST[$fieldname]))
+ $value = $_REQUEST[$fieldname];
+ else
+ $value = trim($_REQUEST[$fieldname]);
+ }
+ $focus->column_fields[$fieldname] = $value;
+ }
+ else {
+ $focus->column_fields[$fieldname] = decode_html($focus->column_fields[$fieldname]);
+ }
+ }
+ $focus->save($currentModule);
+ }
+ }
+}
+
+$parenttab = getParentTab();
+header("Location: index.php?module=$return_module&action=$return_action&parenttab=$parenttab$rstart");
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/Popup.php b/oss/vtiger/trunk/modules/ProjectMilestone/Popup.php
new file mode 100644
index 00000000..7b7329f6
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/Popup.php
@@ -0,0 +1,15 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/ProcessDuplicates.php b/oss/vtiger/trunk/modules/ProjectMilestone/ProcessDuplicates.php
new file mode 100644
index 00000000..bb5047fa
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/ProcessDuplicates.php
@@ -0,0 +1,134 @@
+pquery("SELECT count(*) AS count FROM vtiger_crmentity WHERE crmid=? and deleted=0", array($merge_id));
+ $count = $adb->query_result($result,0,'count');
+
+ if($count > 0)
+ {
+ // First, save the primary record
+ $focus->mode="edit";
+ setObjectValuesFromRequest($focus);
+ $focus->save($module);
+ $rec_values=$focus->column_fields;
+
+ // Remove the id of primary record from the list of records to be deleted.
+ $del_value=explode(",",$recordids,-1);
+ $offset = array_search($merge_id,$del_value);
+ unset($del_value[$offset]);
+
+ // Transfer the related lists of the records to be deleted, to the primary record's related list
+ if(method_exists($focus, 'transferRelatedRecords')){
+ $focus->transferRelatedRecords($module,$del_value,$merge_id);
+ } else {
+ transferRelatedRecords($module,$del_value,$merge_id);
+ }
+
+ // Delete the records by id specified in the list
+ foreach($del_value as $value)
+ {
+ DeleteEntity($_REQUEST['module'],$_REQUEST['return_module'],$focus,$value,"");
+ }
+ }
+
+ ?>
+
+assign("EDIT_DUPLICATE","");
+ if($record_count == 2) {
+ if(isPermitted($currentModule,"EditView",$exploded_id[0]) == 'yes' && isPermitted($currentModule,"EditView",$exploded_id[1]) == 'yes'
+ && isPermitted($currentModule,"Delete",$exploded_id[0]) == 'yes' && isPermitted($currentModule,"Delete",$exploded_id[1]) == 'yes')
+ $smarty->assign("EDIT_DUPLICATE","permitted");
+ }
+ else {
+ if(isPermitted($currentModule,"EditView",$exploded_id[0]) == 'yes' && isPermitted($currentModule,"EditView",$exploded_id[1]) == 'yes' && isPermitted($currentModule,"EditView",$exploded_id[2]) == 'yes'
+ && isPermitted($currentModule,"Delete",$exploded_id[0]) == 'yes' && isPermitted($currentModule,"Delete",$exploded_id[1]) == 'yes' && isPermitted($currentModule,"Delete",$exploded_id[2]) == 'yes')
+ $smarty->assign("EDIT_DUPLICATE","permitted");
+ }
+
+ $all_values_array=getRecordValues($exploded_id,$module);
+ $all_values=$all_values_array[0];
+ $js_arr_val=$all_values_array[1];
+ $fld_array=$all_values_array[2];
+ $js_arr=implode(",",$js_arr_val);
+
+ $imported_records = Array();
+ $sql="select bean_id from vtiger_users_last_import where bean_type=? and deleted=0";
+ $result = $adb->pquery($sql, array($module));
+ $num_rows=$adb->num_rows($result);
+ $count=0;
+ for($i=0; $i<$num_rows;$i++)
+ {
+ foreach($exploded_id as $value)
+ if($value == $adb->query_result($result,$i,"bean_id"))
+ $count++;
+ array_push($imported_records,$adb->query_result($result,$i,"bean_id"));
+ }
+
+ if ($record_count == $count)
+ $no_existing=1;
+ else
+ $no_existing=0;
+
+ $smarty->assign("MOD", $mod_strings);
+ $smarty->assign("APP", $app_strings);
+ $smarty->assign("RECORD_COUNT",$record_count);
+ $smarty->assign("THEME", $theme);
+ $smarty->assign("IMAGE_PATH", $image_path);
+ $smarty->assign("MODULENAME", $module);
+ $smarty->assign("PARENT_TAB", $parent_tab);
+ $smarty->assign("JS_ARRAY", $js_arr);
+ $smarty->assign("ID_ARRAY", $exploded_id);
+ $smarty->assign("IDSTRING",$idstring);
+ $smarty->assign("ALLVALUES", $all_values);
+ $smarty->assign("FIELD_ARRAY", $fld_array);
+ $smarty->assign("IMPORTED_RECORDS", $imported_records);
+ $smarty->assign("NO_EXISTING", $no_existing);
+ $smarty->display("MergeFields.tpl");
+}
+
+?>
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestone.js b/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestone.js
new file mode 100644
index 00000000..3fd0758c
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestone.js
@@ -0,0 +1,8 @@
+/*+**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.0
+ * ("License"); You may not use this file except in compliance with the License
+ * The Original Code is: vtiger CRM Open Source
+ * The Initial Developer of the Original Code is vtiger.
+ * Portions created by vtiger are Copyright (C) vtiger.
+ * All Rights Reserved.
+ ************************************************************************************/
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestone.php b/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestone.php
new file mode 100644
index 00000000..3f2150cb
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestone.php
@@ -0,0 +1,476 @@
+ 'crmid',
+ 'vtiger_projectmilestone' => 'projectmilestoneid',
+ 'vtiger_projectmilestonecf' => 'projectmilestoneid');
+
+ /**
+ * Mandatory for Listing (Related listview)
+ */
+ var $list_fields = Array (
+ /* Format: Field Label => Array(tablename, columnname) */
+ // tablename should not have prefix 'vtiger_'
+ 'Project Milestone Name'=> Array('projectmilestone', 'projectmilestonename'),
+ 'Milestone Date' => Array ('projectmilestone', 'projectmilestonedate'),
+ 'Type' =>Array ('projectmilestone', 'projectmilestonetype'),
+ //'Assigned To' => Array('crmentity','smownerid')
+ );
+ var $list_fields_name = Array(
+ /* Format: Field Label => fieldname */
+ 'Project Milestone Name'=> 'projectmilestonename',
+ 'Milestone Date' => 'projectmilestonedate',
+ 'Type' => 'projectmilestonetype',
+ //'Assigned To' => 'assigned_user_id'
+ );
+
+ // Make the field link to detail view from list view (Fieldname)
+ var $list_link_field = 'projectmilestonename';
+
+ // For Popup listview and UI type support
+ var $search_fields = Array(
+ /* Format: Field Label => Array(tablename, columnname) */
+ // tablename should not have prefix 'vtiger_'
+ 'Project Milestone Name'=> Array('projectmilestone', 'projectmilestonename'),
+ 'Milestone Date' => Array ('projectmilestone', 'projectmilestonedate'),
+ 'Type' =>Array ('projectmilestone', 'projectmilestonetype'),
+ );
+ var $search_fields_name = Array(
+ /* Format: Field Label => fieldname */
+ 'Project Milestone Namee'=> 'projectmilestonename',
+ 'Milestone Date' => 'projectmilestonedate',
+ 'Type' => 'projectmilestonetype',
+ );
+
+ // For Popup window record selection
+ var $popup_fields = Array('projectmilestonename');
+
+ // 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 = 'projectmilestonename';
+
+ // Column value to use on detail view record text display
+ var $def_detailview_recname = 'projectmilestonename';
+
+ // Required Information for enabling Import feature
+ var $required_fields = Array('projectmilestonename'=>1);
+
+ // Callback function list during Importing
+ var $special_functions = Array('set_import_assigned_user');
+
+ var $default_order_by = 'projectmilestonedate';
+ var $default_sort_order='ASC';
+ // Used when enabling/disabling the mandatory fields for the module.
+ // Refers to vtiger_field.fieldname values.
+ var $mandatory_fields = Array('createdtime', 'modifiedtime', 'projectmilestonename', 'projectid');
+
+ function __construct() {
+ global $log, $currentModule;
+ $this->column_fields = getColumnFields($currentModule);
+ $this->db = PearDatabase::getInstance();
+ $this->log = $log;
+ }
+
+ function getSortOrder() {
+ global $currentModule;
+
+ $sortorder = $this->default_sort_order;
+ if($_REQUEST['sorder']) $sortorder = $this->db->sql_escape_string($_REQUEST['sorder']);
+ else if($_SESSION[$currentModule.'_Sort_Order'])
+ $sortorder = $_SESSION[$currentModule.'_Sort_Order'];
+
+ return $sortorder;
+ }
+
+ function getOrderBy() {
+ global $currentModule;
+
+ $use_default_order_by = '';
+ if(PerformancePrefs::getBoolean('LISTVIEW_DEFAULT_SORTING', true)) {
+ $use_default_order_by = $this->default_order_by;
+ }
+
+ $orderby = $use_default_order_by;
+ if($_REQUEST['order_by']) $orderby = $this->db->sql_escape_string($_REQUEST['order_by']);
+ else if($_SESSION[$currentModule.'_Order_By'])
+ $orderby = $_SESSION[$currentModule.'_Order_By'];
+ return $orderby;
+ }
+
+ 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
+ }
+
+ /**
+ * Get list view query (send more WHERE clause condition if required)
+ */
+ function getListQuery($module, $where='') {
+ $query = "SELECT vtiger_crmentity.*, $this->table_name.*";
+
+ // Keep track of tables joined to avoid duplicates
+ $joinedTables = array();
+
+ // Select Custom Field Table Columns if present
+ if(!empty($this->customFieldTable)) $query .= ", " . $this->customFieldTable[0] . ".* ";
+
+ $query .= " FROM $this->table_name";
+
+ $query .= " INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = $this->table_name.$this->table_index";
+
+ $joinedTables[] = $this->table_name;
+ $joinedTables[] = 'vtiger_crmentity';
+
+ // Consider custom table join as well.
+ if(!empty($this->customFieldTable)) {
+ $query .= " INNER JOIN ".$this->customFieldTable[0]." ON ".$this->customFieldTable[0].'.'.$this->customFieldTable[1] .
+ " = $this->table_name.$this->table_index";
+ $joinedTables[] = $this->customFieldTable[0];
+ }
+ $query .= " LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid";
+ $query .= " LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid";
+
+ $joinedTables[] = 'vtiger_users';
+ $joinedTables[] = 'vtiger_groups';
+
+ $linkedModulesQuery = $this->db->pquery("SELECT distinct fieldname, columnname, relmodule FROM vtiger_field" .
+ " INNER JOIN vtiger_fieldmodulerel ON vtiger_fieldmodulerel.fieldid = vtiger_field.fieldid" .
+ " WHERE uitype='10' AND vtiger_fieldmodulerel.module=?", array($module));
+ $linkedFieldsCount = $this->db->num_rows($linkedModulesQuery);
+
+ for($i=0; $i<$linkedFieldsCount; $i++) {
+ $related_module = $this->db->query_result($linkedModulesQuery, $i, 'relmodule');
+ $fieldname = $this->db->query_result($linkedModulesQuery, $i, 'fieldname');
+ $columnname = $this->db->query_result($linkedModulesQuery, $i, 'columnname');
+
+ $other = CRMEntity::getInstance($related_module);
+ vtlib_setup_modulevars($related_module, $other);
+
+ if(!in_array($other->table_name, $joinedTables)) {
+ $query .= " LEFT JOIN $other->table_name ON $other->table_name.$other->table_index = $this->table_name.$columnname";
+ $joinedTables[] = $other->table_name;
+ }
+ }
+
+ global $current_user;
+ $query .= $this->getNonAdminAccessControlQuery($module,$current_user);
+ $query .= " WHERE vtiger_crmentity.deleted = 0 ".$usewhere;
+ return $query;
+ }
+
+ /**
+ * Apply security restriction (sharing privilege) query part for List view.
+ */
+ function getListViewSecurityParameter($module) {
+ global $current_user;
+ require('user_privileges/user_privileges_'.$current_user->id.'.php');
+ require('user_privileges/sharing_privileges_'.$current_user->id.'.php');
+
+ $sec_query = '';
+ $tabid = getTabid($module);
+
+ if($is_admin==false && $profileGlobalPermission[1] == 1 && $profileGlobalPermission[2] == 1
+ && $defaultOrgSharingPermission[$tabid] == 3) {
+
+ $sec_query .= " AND (vtiger_crmentity.smownerid in($current_user->id) OR vtiger_crmentity.smownerid IN
+ (
+ SELECT vtiger_user2role.userid FROM vtiger_user2role
+ INNER JOIN vtiger_users ON vtiger_users.id=vtiger_user2role.userid
+ INNER JOIN vtiger_role ON vtiger_role.roleid=vtiger_user2role.roleid
+ WHERE vtiger_role.parentrole LIKE '".$current_user_parent_role_seq."::%'
+ )
+ OR vtiger_crmentity.smownerid IN
+ (
+ SELECT shareduserid FROM vtiger_tmp_read_user_sharing_per
+ WHERE userid=".$current_user->id." AND tabid=".$tabid."
+ )
+ OR
+ (";
+
+ // Build the query based on the group association of current user.
+ if(sizeof($current_user_groups) > 0) {
+ $sec_query .= " vtiger_groups.groupid IN (". implode(",", $current_user_groups) .") OR ";
+ }
+ $sec_query .= " vtiger_groups.groupid IN
+ (
+ SELECT vtiger_tmp_read_group_sharing_per.sharedgroupid
+ FROM vtiger_tmp_read_group_sharing_per
+ WHERE userid=".$current_user->id." and tabid=".$tabid."
+ )";
+ $sec_query .= ")
+ )";
+ }
+ return $sec_query;
+ }
+
+ /**
+ * Create query to export the records.
+ */
+ function create_export_query($where)
+ {
+ global $current_user;
+ $thismodule = $_REQUEST['module'];
+
+ include("include/utils/ExportUtils.php");
+
+ //To get the Permitted fields query and the permitted fields list
+ $sql = getPermittedFieldsQuery($thismodule, "detail_view");
+
+ $fields_list = getFieldsListFromQuery($sql);
+
+ $query = "SELECT $fields_list, vtiger_users.user_name AS user_name
+ FROM vtiger_crmentity INNER JOIN $this->table_name ON vtiger_crmentity.crmid=$this->table_name.$this->table_index";
+
+ if(!empty($this->customFieldTable)) {
+ $query .= " INNER JOIN ".$this->customFieldTable[0]." ON ".$this->customFieldTable[0].'.'.$this->customFieldTable[1] .
+ " = $this->table_name.$this->table_index";
+ }
+
+ $query .= " LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid";
+ $query .= " LEFT JOIN vtiger_users ON vtiger_crmentity.smownerid = vtiger_users.id and vtiger_users.status='Active'";
+
+ $linkedModulesQuery = $this->db->pquery("SELECT distinct fieldname, columnname, relmodule FROM vtiger_field" .
+ " INNER JOIN vtiger_fieldmodulerel ON vtiger_fieldmodulerel.fieldid = vtiger_field.fieldid" .
+ " WHERE uitype='10' AND vtiger_fieldmodulerel.module=?", array($thismodule));
+ $linkedFieldsCount = $this->db->num_rows($linkedModulesQuery);
+
+ for($i=0; $i<$linkedFieldsCount; $i++) {
+ $related_module = $this->db->query_result($linkedModulesQuery, $i, 'relmodule');
+ $fieldname = $this->db->query_result($linkedModulesQuery, $i, 'fieldname');
+ $columnname = $this->db->query_result($linkedModulesQuery, $i, 'columnname');
+
+ $other = CRMEntity::getInstance($related_module);
+ vtlib_setup_modulevars($related_module, $other);
+
+ $query .= " LEFT JOIN $other->table_name ON $other->table_name.$other->table_index = $this->table_name.$columnname";
+ }
+
+ $query .= $this->getNonAdminAccessControlQuery($thismodule,$current_user);
+ $where_auto = " vtiger_crmentity.deleted=0";
+
+ if($where != '') $query .= " WHERE ($where) AND $where_auto";
+ else $query .= " WHERE $where_auto";
+
+ return $query;
+ }
+
+ /**
+ * Initialize this instance for importing.
+ */
+ function initImport($module) {
+ $this->db = PearDatabase::getInstance();
+ $this->initImportableFields($module);
+ }
+
+ /**
+ * Create list query to be shown at the last step of the import.
+ * Called From: modules/Import/UserLastImport.php
+ */
+ function create_import_query($module) {
+ global $current_user;
+ $query = "SELECT vtiger_crmentity.crmid, case when (vtiger_users.user_name not like '') then vtiger_users.user_name else vtiger_groups.groupname end as user_name, $this->table_name.* FROM $this->table_name
+ INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = $this->table_name.$this->table_index
+ LEFT JOIN vtiger_users_last_import ON vtiger_users_last_import.bean_id=vtiger_crmentity.crmid
+ LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid
+ LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid
+ WHERE vtiger_users_last_import.assigned_user_id='$current_user->id'
+ AND vtiger_users_last_import.bean_type='$module'
+ AND vtiger_users_last_import.deleted=0";
+ return $query;
+ }
+
+ /**
+ * Delete the last imported records.
+ */
+ function undo_import($module, $user_id) {
+ global $adb;
+ $count = 0;
+ $query1 = "select bean_id from vtiger_users_last_import where assigned_user_id=? AND bean_type='$module' AND deleted=0";
+ $result1 = $adb->pquery($query1, array($user_id)) or die("Error getting last import for undo: ".mysql_error());
+ while ( $row1 = $adb->fetchByAssoc($result1))
+ {
+ $query2 = "update vtiger_crmentity set deleted=1 where crmid=?";
+ $result2 = $adb->pquery($query2, array($row1['bean_id'])) or die("Error undoing last import: ".mysql_error());
+ $count++;
+ }
+ return $count;
+ }
+
+ /**
+ * Transform the value while exporting
+ */
+ function transform_export_value($key, $value) {
+ return parent::transform_export_value($key, $value);
+ }
+
+ /**
+ * Function which will set the assigned user id for import record.
+ */
+ function set_import_assigned_user()
+ {
+ global $current_user, $adb;
+ $record_user = $this->column_fields["assigned_user_id"];
+
+ if($record_user != $current_user->id){
+ $sqlresult = $adb->pquery("select id from vtiger_users where id = ? union select groupid as id from vtiger_groups where groupid = ?", array($record_user, $record_user));
+ if($this->db->num_rows($sqlresult)!= 1) {
+ $this->column_fields["assigned_user_id"] = $current_user->id;
+ } else {
+ $row = $adb->fetchByAssoc($sqlresult, -1, false);
+ if (isset($row['id']) && $row['id'] != -1) {
+ $this->column_fields["assigned_user_id"] = $row['id'];
+ } else {
+ $this->column_fields["assigned_user_id"] = $current_user->id;
+ }
+ }
+ }
+ }
+
+ /**
+ * Function which will give the basic query to find duplicates
+ */
+ function getDuplicatesQuery($module,$table_cols,$field_values,$ui_type_arr,$select_cols='') {
+ $select_clause = "SELECT ". $this->table_name .".".$this->table_index ." AS recordid, vtiger_users_last_import.deleted,".$table_cols;
+
+ // Select Custom Field Table Columns if present
+ if(isset($this->customFieldTable)) $query .= ", " . $this->customFieldTable[0] . ".* ";
+
+ $from_clause = " FROM $this->table_name";
+
+ $from_clause .= " INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = $this->table_name.$this->table_index";
+
+ // Consider custom table join as well.
+ if(isset($this->customFieldTable)) {
+ $from_clause .= " INNER JOIN ".$this->customFieldTable[0]." ON ".$this->customFieldTable[0].'.'.$this->customFieldTable[1] .
+ " = $this->table_name.$this->table_index";
+ }
+ $from_clause .= " LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid
+ LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid";
+
+ $where_clause = " WHERE vtiger_crmentity.deleted = 0";
+ $where_clause .= $this->getListViewSecurityParameter($module);
+
+ if (isset($select_cols) && trim($select_cols) != '') {
+ $sub_query = "SELECT $select_cols FROM $this->table_name AS t " .
+ " INNER JOIN vtiger_crmentity AS crm ON crm.crmid = t.".$this->table_index;
+ // Consider custom table join as well.
+ if(isset($this->customFieldTable)) {
+ $sub_query .= " LEFT JOIN ".$this->customFieldTable[0]." tcf ON tcf.".$this->customFieldTable[1]." = t.$this->table_index";
+ }
+ $sub_query .= " WHERE crm.deleted=0 GROUP BY $select_cols HAVING COUNT(*)>1";
+ } else {
+ $sub_query = "SELECT $table_cols $from_clause $where_clause GROUP BY $table_cols HAVING COUNT(*)>1";
+ }
+
+
+ $query = $select_clause . $from_clause .
+ " LEFT JOIN vtiger_users_last_import ON vtiger_users_last_import.bean_id=" . $this->table_name .".".$this->table_index .
+ " INNER JOIN (" . $sub_query . ") AS temp ON ".get_on_clause($field_values,$ui_type_arr,$module) .
+ $where_clause .
+ " ORDER BY $table_cols,". $this->table_name .".".$this->table_index ." ASC";
+
+ return $query;
+ }
+
+ /**
+ * 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;
+
+ $projectmilestoneTabid = getTabid($modulename);
+ // Mark the module as Standard module
+ $adb->pquery('UPDATE vtiger_tab SET customized=0 WHERE name=?', array($modulename));
+
+ $maxSequenceQuery = $adb->query("SELECT max(sequence) as maxsequence FROM vtiger_customerportal_tabs");
+ $maxSequence = $adb->query_result($maxSequenceQuery, 0, 'maxsequence');
+ $nextSequence = $maxSequence+1;
+
+ $adb->query("INSERT INTO vtiger_customerportal_tabs(tabid,visible,sequence) VALUES ($projectmilestoneTabid,1,$nextSequence)");
+ $adb->query("INSERT INTO vtiger_customerportal_prefs(tabid,prefkey,prefvalue) VALUES ($projectmilestoneTabid,'showrelatedinfo',1)");
+ } 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.
+ }
+ }
+
+ /**
+ * Handle saving related module information.
+ * NOTE: This function has been added to CRMEntity (base class).
+ * You can override the behavior by re-defining it here.
+ */
+ // function save_related_module($module, $crmid, $with_module, $with_crmid) { }
+
+ /**
+ * Handle deleting related module information.
+ * NOTE: This function has been added to CRMEntity (base class).
+ * You can override the behavior by re-defining it here.
+ */
+ //function delete_related_module($module, $crmid, $with_module, $with_crmid) { }
+
+ /**
+ * 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) { }
+}
+?>
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestoneAjax.php b/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestoneAjax.php
new file mode 100644
index 00000000..efae0a94
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/ProjectMilestoneAjax.php
@@ -0,0 +1,11 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/QuickCreate.php b/oss/vtiger/trunk/modules/ProjectMilestone/QuickCreate.php
new file mode 100644
index 00000000..78fe10f6
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/QuickCreate.php
@@ -0,0 +1,11 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/Save.php b/oss/vtiger/trunk/modules/ProjectMilestone/Save.php
new file mode 100644
index 00000000..b595d9e1
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/Save.php
@@ -0,0 +1,53 @@
+mode = $mode;
+if($record)$focus->id = $record;
+
+if($_REQUEST['assigntype'] == 'U') {
+ $focus->column_fields['assigned_user_id'] = $_REQUEST['assigned_user_id'];
+} elseif($_REQUEST['assigntype'] == 'T') {
+ $focus->column_fields['assigned_user_id'] = $_REQUEST['assigned_group_id'];
+}
+
+$focus->save($currentModule);
+$return_id = $focus->id;
+
+$search = vtlib_purify($_REQUEST['search_url']);
+
+$parenttab = getParentTab();
+if($_REQUEST['return_module'] != '') {
+ $return_module = vtlib_purify($_REQUEST['return_module']);
+} else {
+ $return_module = $currentModule;
+}
+
+if($_REQUEST['return_action'] != '') {
+ $return_action = vtlib_purify($_REQUEST['return_action']);
+} else {
+ $return_action = "DetailView";
+}
+
+if($_REQUEST['return_id'] != '') {
+ $return_id = vtlib_purify($_REQUEST['return_id']);
+}
+
+header("Location: index.php?action=$return_action&module=$return_module&record=$return_id&parenttab=$parenttab&start=".vtlib_purify($_REQUEST['pagenumber']).$search);
+
+?>
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/Settings.php b/oss/vtiger/trunk/modules/ProjectMilestone/Settings.php
new file mode 100644
index 00000000..980dd078
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/Settings.php
@@ -0,0 +1,13 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/TagCloud.php b/oss/vtiger/trunk/modules/ProjectMilestone/TagCloud.php
new file mode 100644
index 00000000..8343cd5b
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/TagCloud.php
@@ -0,0 +1,11 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/UnifiedSearch.php b/oss/vtiger/trunk/modules/ProjectMilestone/UnifiedSearch.php
new file mode 100644
index 00000000..9a37320c
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/UnifiedSearch.php
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/index.php b/oss/vtiger/trunk/modules/ProjectMilestone/index.php
new file mode 100644
index 00000000..b7add8d8
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/index.php
@@ -0,0 +1,15 @@
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/language/en_us.lang.php b/oss/vtiger/trunk/modules/ProjectMilestone/language/en_us.lang.php
new file mode 100644
index 00000000..70c928fc
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/language/en_us.lang.php
@@ -0,0 +1,47 @@
+'Project Milestones',
+ 'LBL_MODULE_TITLE'=>'Project Milestones',
+ 'LBL_NEW_OPERATION'=>'New Project Milestone',
+ 'LBL_MILESTONES'=>'Project Milestones',
+ 'LBL_MILESTONE'=>'Project Milestone',
+ 'Project Milestone ID'=>'Milestone ID',
+ 'projectmilestones' => 'Project Milestones',
+ //added this to translate the module name in the main app menu
+ 'ProjectMilestone'=>'Project Milestones',
+ //
+ 'SINGLE_ProjectMilestone' => 'Project Milestone',
+ 'LBL_CUSTOM_INFORMATION' => 'Custom Information',
+ 'LBL_PROJECT_MILESTONE_INFORMATION' => 'Project Milestone Information',
+ 'LBL_DESCRIPTION_INFORMATION' => 'Description Information',
+ 'Assigned To' => 'Assigned To',
+ 'Milestone Date' => 'Milestone Date',
+ 'Milestone' => 'Milestone',
+ 'Type'=>'Type',
+ //'linktoproject'=>'Link To',
+ 'Related Project' => 'Related Project',
+ 'Related To' => 'Related To',
+ 'projectid' => 'Related To',
+ 'administrative' => 'administrative',
+ 'operative' => 'operative',
+ 'other' => 'other',
+ 'Created Time' => 'Created Time',
+ 'Modified Time' => 'Modified Time',
+ 'description' => 'Description',
+ 'Description' => 'Description',
+ //added for related lists
+ 'Project Milestone Name' => 'Milestone Name',
+ 'Project Milestone No' => 'Milestone No',
+
+);
+
+?>
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/language/zh_cn.lang.php b/oss/vtiger/trunk/modules/ProjectMilestone/language/zh_cn.lang.php
new file mode 100644
index 00000000..806597bf
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/language/zh_cn.lang.php
@@ -0,0 +1,60 @@
+'Project Milestones',
+ 'LBL_MODULE_TITLE'=>'Project Milestones',
+ 'LBL_NEW_OPERATION'=>'New Project Milestone',
+ 'LBL_MILESTONES'=>'Project Milestones',
+ 'LBL_MILESTONE'=>'Project Milestone',
+ 'Project Milestone ID'=>'Milestone ID',
+ 'projectmilestones' => 'Project Milestones',
+ //added this to translate the module name in the main app menu
+ 'ProjectMilestone'=>'Project Milestones',
+ //
+ 'SINGLE_ProjectMilestone' => 'Project Milestone',
+ 'LBL_CUSTOM_INFORMATION' => 'Custom Information',
+ 'LBL_PROJECT_MILESTONE_INFORMATION' => 'Project Milestone Information',
+ 'LBL_DESCRIPTION_INFORMATION' => 'Description Information',
+ 'Assigned To' => 'Assigned To',
+ 'Milestone Date' => 'Milestone Date',
+ 'Milestone' => 'Milestone',
+ 'Type'=>'Type',
+ //'linktoproject'=>'Link To',
+ 'Related Project' => 'Related Project',
+ 'Related To' => 'Related To',
+ 'projectid' => 'Related To',
+ 'administrative' => 'administrative',
+ 'operative' => 'operative',
+ 'other' => 'other',
+ 'Created Time' => 'Created Time',
+ 'Modified Time' => 'Modified Time',
+ 'description' => 'Description',
+ 'Description' => 'Description',
+ //added for related lists
+ 'Project Milestone Name' => 'Milestone Name',
+ 'Project Milestone No' => 'Milestone No',
+
+);
+
+?>
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/schema.xml b/oss/vtiger/trunk/modules/ProjectMilestone/schema.xml
new file mode 100644
index 00000000..32488df8
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/schema.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ vtiger_projectmilestone
+
+
+
+ vtiger_projectmilestonecf
+
+
+
+
diff --git a/oss/vtiger/trunk/modules/ProjectMilestone/updateRelations.php b/oss/vtiger/trunk/modules/ProjectMilestone/updateRelations.php
new file mode 100644
index 00000000..9ee5399f
--- /dev/null
+++ b/oss/vtiger/trunk/modules/ProjectMilestone/updateRelations.php
@@ -0,0 +1,46 @@
+delete_related_module($currentModule, $forCRMRecord, $destinationModule, $ids);
+ }
+} else {
+ if(!empty($_REQUEST['idlist'])) {
+ // Split the string of ids
+ $ids = explode (";",trim($idlist,";"));
+ } else if(!empty($_REQUEST['entityid'])){
+ $ids = $_REQUEST['entityid'];
+ }
+ if(!empty($ids)) {
+ $focus->save_related_module($currentModule, $forCRMRecord, $destinationModule, $ids);
+ }
+}
+header("Location: index.php?module=$currentModule&record=$forCRMRecord&action=$action&parenttab=$parenttab");
+?>
\ No newline at end of file