diff --git a/layouts/v7/modules/Users/UserViewHeader.tpl b/layouts/v7/modules/Users/UserViewHeader.tpl
index 0b11b52f635115d94ca1d40204e94333dba876b0..0aaa035d57c8a0e97eb0dc77aebf792d496ff1c2 100644
--- a/layouts/v7/modules/Users/UserViewHeader.tpl
+++ b/layouts/v7/modules/Users/UserViewHeader.tpl
@@ -36,7 +36,7 @@
                         {$RECORD->getName()}
                     </span>
                 </div>
-                <div class="pull-right col-md-7">
+                <div class="pull-right col-md-7 detailViewButtoncontainer">
                     <div class="btn-group pull-right">
                         {foreach item=DETAIL_VIEW_BASIC_LINK from=$DETAILVIEW_LINKS['DETAILVIEWBASIC']}
                             <button class="btn btn-default {if $DETAIL_VIEW_BASIC_LINK->getLabel() eq 'LBL_EDIT'}{/if}" id="{$MODULE}_detailView_basicAction_{Vtiger_Util_Helper::replaceSpaceWithUnderScores($DETAIL_VIEW_BASIC_LINK->getLabel())}"
diff --git a/layouts/v7/modules/Vtiger/uitypes/UserRole.tpl b/layouts/v7/modules/Vtiger/uitypes/UserRole.tpl
index 1375eee3943a5f3a259c7f0ff3c2b22bf3fc85eb..ebf9e7b3758bcbebf0984cc687271080d6536ca5 100644
--- a/layouts/v7/modules/Vtiger/uitypes/UserRole.tpl
+++ b/layouts/v7/modules/Vtiger/uitypes/UserRole.tpl
@@ -21,7 +21,7 @@
         {/if}
         >
     {foreach item=PICKLIST_VALUE key=PICKLIST_NAME from=$PICKLIST_VALUES}
-	<option value="{$PICKLIST_VALUE}" {if $FIELD_MODEL->get('fieldvalue') eq $PICKLIST_VALUE} selected {/if}>{vtranslate($PICKLIST_NAME, $MODULE)}</option>
+	<option value="{$PICKLIST_VALUE}" {if $FIELD_MODEL->get('fieldvalue') eq $PICKLIST_VALUE} selected {/if}>{$PICKLIST_NAME}</option>
 {/foreach}
 </select>
 {/strip}
\ No newline at end of file
diff --git a/modules/Settings/Vtiger/models/Module.php b/modules/Settings/Vtiger/models/Module.php
index de6382c132dec24909c8a66bda9f6ab2bde80bb6..04b63db9535fb571cf1445ff3a0394aa65e3ecf3 100644
--- a/modules/Settings/Vtiger/models/Module.php
+++ b/modules/Settings/Vtiger/models/Module.php
@@ -215,4 +215,18 @@ class Settings_Vtiger_Module_Model extends Vtiger_Base_Model {
 		return $settingsMenuList;
 	}
 
+	public function getModuleIcon() {
+		$moduleName = $this->getName();
+		$moduleModel = Vtiger_Module_Model::getInstance($moduleName);
+		if ($moduleModel) {
+			$moduleIcon = $moduleModel->getModuleIcon();
+		} else {
+			$lowerModuleName = strtolower($moduleName);
+			$title = vtranslate($moduleName, $moduleName);
+			$moduleIcon = "<i class='vicon-$lowerModuleName' title='$title'></i>";
+		}
+
+		return $moduleIcon;
+	}	
+
 }
diff --git a/packages/vtiger/optional/CustomerPortal.zip b/packages/vtiger/optional/CustomerPortal.zip
index eab50347533eb80d0f68bbb248d590855f4b65e5..7fc52788c026f98a3b8d8d8e1b5f586934a7e307 100644
Binary files a/packages/vtiger/optional/CustomerPortal.zip and b/packages/vtiger/optional/CustomerPortal.zip differ
diff --git a/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/CustomerPortalDashboard.tpl b/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/CustomerPortalDashboard.tpl
index bbefc10c7056ed12e5ad4c05ea639e00867e6c19..13f2aa1e232ffbbedd0dd64e778107db6bc38fb2 100644
--- a/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/CustomerPortalDashboard.tpl
+++ b/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/CustomerPortalDashboard.tpl
@@ -19,25 +19,6 @@
 				</textarea>
 			</div>
 		</div><br>
-		<div>
-			{if isset($WIDGETS_MODULE_LIST['HelpDesk'])}
-				<div class="portal-chart-widget-container" >
-					<div class="portal-chart-header" >
-						<h5>{vtranslate('LBL_CHARTS',$QUALIFIED_MODULE)}</h5>
-					</div>
-					<div class="portal-chart-content" >
-						{foreach from=$CHARTS['charts'] key=KEY item=VALUE}
-							<div class="checkbox label-checkbox" style="padding: 10px 5px;">
-								<label>
-									<input id="{$KEY}" type="checkbox" class="chartsInfo" value="{$KEY}" name="charts[]" {if $VALUE}checked{/if}/>
-									&nbsp;&nbsp{vtranslate({$KEY},$QUALIFIED_MODULE)}
-								</label>
-							</div>
-						{/foreach}
-					</div>
-				</div>
-			{/if}
-		</div><br><br>
 		{foreach from=$WIDGETS['widgets'] key=module item=status}
 			{if $module eq 'HelpDesk' && isset($WIDGETS_MODULE_LIST['HelpDesk'])}
 				<div class="portal-record-widget-container" >
@@ -72,11 +53,11 @@
 								{if isset($WIDGETS_MODULE_LIST[$key])}
 									{foreach from=$value key=key1 item=value1}
 										{if $value1 == 1}
-											<li class="portal-shortcut-list"  data-field="{$key1}">&nbsp;<div class="btn btn-large">{vtranslate({$key1},$QUALIFIED_MODULE)}&nbsp;&nbsp; {*{if $key neq 'HelpDesk'}<span class="deleteShortcut">X</span>{/if}*}</div></li>
-											{/if}
-										{/foreach}
-									{/if}
-								{/foreach}
+											<li class="portal-shortcut-list" data-field="{$key1}">&nbsp;<div class="btn btn-large">{vtranslate({$key1},$QUALIFIED_MODULE)}&nbsp;&nbsp; {*{if $key neq 'HelpDesk'}<span class="deleteShortcut">X</span>{/if}*}</div></li>
+										{/if}
+									{/foreach}
+								{/if}
+							{/foreach}
 						</ul>
 					</div>
 				</div>
diff --git a/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/Index.tpl b/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/Index.tpl
index 149501c8fdbc07b9566ef358fbcd068b9a5e4e02..21e06d4df1cdb1e515188f9b2c4918f1f7c610d0 100644
--- a/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/Index.tpl
+++ b/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/Index.tpl
@@ -10,26 +10,9 @@
 {strip}
 	<div class="listViewPageDiv" id="listViewContent">
 		<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
-			<br>
 			<br>
 			<form id="customerPortalForm" name="customerPortalForm" action="index.php" method="POST" class="form-horizontal">
 				<input type="hidden" name="portalModulesInfo" value="" />
-				<div class="col-sm-12 col-xs-12 input-group">					
-					<div class="form-group">
-						<label for="privileges" class="col-sm-4 control-label fieldLabel"><span>{vtranslate('LBL_PRIVILEGES', $QUALIFIED_MODULE)}</span></label>
-						<div class="fieldValue col-lg-3 col-md-3 col-sm-3 input-group">
-							<select name="privileges" class="select2 inputElement">
-								{foreach item=USER_MODEL from=$USER_MODELS}
-									{assign var=USER_ID value=$USER_MODEL->getId()}
-									<option value="{$USER_ID}" {if $CURRENT_PORTAL_USER eq $USER_ID} selected {/if}>{$USER_MODEL->getName()}</option>
-								{/foreach}
-							</select>
-							<div class="input-group-addon input-select-addon">
-								<a href="#" rel="tooltip" title="{vtranslate('LBL_PREVILEGES_MESSAGE', $QUALIFIED_MODULE)}"><i class="fa fa-info-circle"></i></a>
-							</div>
-						</div>
-					</div>
-				</div>
 				<div class="col-sm-12 col-xs-12 input-group">					
 					<div class="form-group">
 						<label for="defaultAssignee" class="col-sm-4 control-label fieldLabel"><span>{vtranslate('LBL_DEFAULT_ASSIGNEE', $QUALIFIED_MODULE)}</span></label>
@@ -58,7 +41,7 @@
 					<div class="form-group">
 						<label for="portal-url" class="col-sm-4 control-label fieldLabel">{vtranslate('LBL_PORTAL_URL', $QUALIFIED_MODULE)}</label>
 						<div class="col-sm-5">
-							<a target="_blank" href="{$PORTAL_URL}" class="help-inline" style="width: 300px;">{$PORTAL_URL}</a>
+							<a target="_blank" href="{$PORTAL_URL}" class="help-inline" style="width: 300px;color:blue;">{$PORTAL_URL}</a>
 							<div class="pull-left input-group-addon input-select-addon">
 								<a href="#" rel="tooltip" title="{vtranslate('LBL_PORTAL_URL_MESSAGE', $QUALIFIED_MODULE)}"><i class="fa fa-info-circle"></i></a>
 							</div>
@@ -103,7 +86,6 @@
 						<div id="dashboardContent" class="show" >
 							<h4>{vtranslate('LBL_HOME_LAYOUT',$QUALIFIED_MODULE)}</h4>
 							<hr class="hrHeader">
-							<input type="hidden" name="defaultCharts" value='{Vtiger_Functions::jsonEncode($CHARTS,true)}'/>
 							<input type="hidden" name="defaultWidgets" value='{Vtiger_Functions::jsonEncode($WIDGETS,true)}'/>
 							{include file='CustomerPortalDashboard.tpl'|@vtemplate_path:$QUALIFIED_MODULE}
 						</div>
diff --git a/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/resources/CustomerPortal.js b/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/resources/CustomerPortal.js
index 8dd9b0e4e96cd26db9cc3728c067f3caf410f54f..431ffa807bebc2b6e13dce6a2611c9f77772cef0 100644
--- a/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/resources/CustomerPortal.js
+++ b/pkg/vtiger/modules/CustomerPortal/layouts/v7/modules/Settings/CustomerPortal/resources/CustomerPortal.js
@@ -167,8 +167,6 @@ Vtiger.Class('Settings_Customer_Portal_Js', {}, {
 		}
 
 		var activeWidgets = {};
-		var activeCharts = {};
-		var defaultCharts = JSON.parse(jQuery('input[name="defaultCharts"]').val());
 		var defaultWidgets = JSON.parse(jQuery('input[name="defaultWidgets"]').val());
 
 		var defaultWidgetModules = ['HelpDesk', 'Faq', 'Documents'];
@@ -187,26 +185,12 @@ Vtiger.Class('Settings_Customer_Portal_Js', {}, {
 				activeWidgets[module] = parseInt(defaultWidgets.widgets[module]);
 		});
 
-		var chartsInfo = jQuery("input.chartsInfo");
-		jQuery.each(chartsInfo, function (index, chart) {
-			var element = jQuery(chart);
-			if (element.is(":checked")) {
-				activeCharts[element.attr('id')] = 1;
-			}
-			else {
-				activeCharts[element.attr('id')] = 0;
-			}
-		});
-		if (chartsInfo.length === 0) {
-			activeCharts = defaultCharts.charts;
-		}
 		if (widgetsInfo.length === 0) {
 			activeWidgets = defaultWidgets.widgets;
 		}
 		formData['moduleFieldsInfo'] = selectedFields;
 		formData['relatedModuleList'] = relatedModuleInfo;
 		formData['recordsVisible'] = recordsVisible;
-		formData['activeCharts'] = JSON.stringify(activeCharts);
 		formData['activeWidgets'] = JSON.stringify(activeWidgets);
 		formData['recordPermissions'] = recordPermissionsInfo;
 		return formData;
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/Config.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/Config.php
new file mode 100644
index 0000000000000000000000000000000000000000..7cbb94e55f5554aebd38c21e01d5d5dc0e8786e3
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/Config.php
@@ -0,0 +1,15 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_Config {
+
+	static $DEFAULT_PAGE_LIMIT = 50;
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/api.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/api.php
new file mode 100644
index 0000000000000000000000000000000000000000..8c02e4a8a52b31b25489a01deb49ee8d56d04d06
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/api.php
@@ -0,0 +1,84 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+include_once 'include.inc';
+
+class CustomerPortal_API_EntryPoint {
+
+	protected static function authenticate(CustomerPortal_API_Abstract $controller, CustomerPortal_API_Request $request) {
+		if (!isset($_SERVER['PHP_AUTH_USER'])) {
+			header('WWW-Authenticate: Basic realm="Customer Portal"');
+			header('HTTP/1.0 401 Unauthorized');
+			throw new Exception("Login Required", 1412);
+			exit;
+		} else {
+			// Handling the case Contacts module is disabled 
+			if (!vtlib_isModuleActive("Contacts")) {
+				throw new Exception("Contacts module is disabled", 1412);
+			}
+
+			$ok = $controller->authenticatePortalUser($request->get('username'), $request->get('password'));
+			if (!$ok) {
+				throw new Exception("Login failed", 1412);
+			}
+		}
+	}
+
+	static function process(CustomerPortal_API_Request $request) {
+		$operation = $request->getOperation();
+		$response = false;
+		preg_match("/[0-9a-zA-z]*/", $operation, $match);
+
+		if ($operation == $match[0]) {
+			$operationFile = sprintf('/apis/%s.php', $operation);
+			$operationClass = sprintf("CustomerPortal_%s", $operation);
+			include_once dirname(__FILE__).$operationFile;
+			$operationController = new $operationClass;
+
+			try {
+				self::authenticate($operationController, $request);
+
+				//setting active user language as Portal user language 
+				$current_user = $operationController->getActiveUser();
+				$portal_language = $request->getLanguage();
+				$current_user->column_fields["language"] = $portal_language;
+				$current_user->language = $portal_language;
+
+				$response = $operationController->process($request);
+			} catch (Exception $e) {
+				$response = new CustomerPortal_API_Response();
+				$response->setError($e->getCode(), $e->getMessage());
+			}
+		} else {
+			$response = new CustomerPortal_API_Response();
+			$response->setError(1404, 'Operation not found: '.$operation);
+		}
+
+		if ($response !== false) {
+			echo $response->emitJSON();
+		}
+	}
+
+}
+
+/** Take care of stripping the slashes */
+function stripslashes_recursive($value) {
+	$value = is_array($value) ? array_map('stripslashes_recursive', $value) : stripslashes($value);
+	return $value;
+}
+
+$clientRequestValues = $_POST;
+if (get_magic_quotes_gpc()) {
+	$clientRequestValues = stripslashes_recursive($clientRequestValues);
+}
+
+$clientRequestValuesRaw = array();
+CustomerPortal_API_EntryPoint::process(new CustomerPortal_API_Request($clientRequestValues, $clientRequestValuesRaw));
+
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/AbstractApi.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/AbstractApi.php
new file mode 100644
index 0000000000000000000000000000000000000000..920f013eea9978a8540d5516876095a39f81b715
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/AbstractApi.php
@@ -0,0 +1,165 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+abstract class CustomerPortal_API_Abstract {
+
+	private $activeUser = false;
+	private $activeCustomer = false;
+	protected $resolvedValueCache = array();
+
+	protected function initActiveUser($user) {
+		$this->activeUser = $user;
+	}
+
+	protected function hasActiveUser() {
+		$user = $this->getActiveUser();
+		return ($user !== false);
+	}
+
+	protected function setActiveUser($user) {
+		$this->initActiveUser($user);
+	}
+
+	public function getActiveUser() {
+		return $this->activeUser;
+	}
+
+	protected function initActiveCustomer($customer) {
+		$this->activeCustomer = $customer;
+	}
+
+	protected function hasActiveCustomer() {
+		$customer = $this->getActiveCustomer();
+		return ($customer !== false);
+	}
+
+	protected function setActiveCustomer($customer) {
+		$this->initActiveCustomer($customer);
+	}
+
+	protected function getActiveCustomer() {
+		return $this->activeCustomer;
+	}
+
+	function authenticatePortalUser($username, $password) {
+		global $adb;
+		$current_date = date("Y-m-d");
+		$sql = "SELECT id, user_name, user_password,last_login_time, isactive, support_start_date, support_end_date, cryptmode FROM vtiger_portalinfo
+					INNER JOIN vtiger_customerdetails ON vtiger_portalinfo.id=vtiger_customerdetails.customerid
+					INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid=vtiger_portalinfo.id
+						WHERE vtiger_crmentity.deleted=0 AND user_name=? AND isactive=1 AND vtiger_customerdetails.portal=1
+						AND (vtiger_customerdetails.support_start_date <= ? OR vtiger_customerdetails.support_start_date IS NULL)
+						AND (vtiger_customerdetails.support_end_date >= ? OR vtiger_customerdetails.support_end_date IS NULL)";
+
+		$result = $adb->pquery($sql, array($username, $current_date, $current_date));
+		$num_rows = $adb->num_rows($result);
+
+		$isAuthenticated = false;
+		if ($num_rows >= 0) {
+			for ($i = 0; $i < $num_rows; ++$i) {
+				$customerId = $adb->query_result($result, $i, 'id');
+				if (Vtiger_Functions::compareEncryptedPassword($password, $adb->query_result($result, $i, 'user_password'), $adb->query_result($result, $i, 'cryptmode'))) {
+					break;
+				} else {
+					$customerId = null;
+				}
+			}
+			$isActive = $adb->query_result($result, $i, 'isactive');
+			if ($customerId) {
+				$support_end_date = $adb->query_result($result, $i, 'support_end_date');
+				if ($isActive && ($support_end_date >= $current_date || $support_end_date == null)) {
+					$current_customer = CRMEntity::getInstance('Contacts');
+					$current_customer->id = $customerId;
+					$userName = $adb->query_result($result, $i, 'user_name');
+					$current_customer->username = $userName;
+					$this->setActiveCustomer($current_customer);
+
+					global $current_user;
+					$current_user = CRMEntity::getInstance('Users');
+					$userid = Users::getActiveAdminId();
+					$current_user->retrieveCurrentUserInfoFromFile($userid);
+					$this->setActiveUser($current_user);
+					$isAuthenticated = true;
+				}
+			} else if ($isActive && $support_end_date <= $current_date) {
+				throw new Exception("Access to the portal was disabled on ".$support_end_date, 1413);
+			} else if ($isActive == 0) {
+				throw new Exception("Portal access has not been enabled for this account.", 1414);
+			}
+		}
+		return $isAuthenticated;
+	}
+
+	protected function getParent($contactId) {
+		$sql = sprintf("SELECT account_id FROM Contacts WHERE id = '%s';", $contactId);
+		$result = vtws_query($sql, $this->getActiveUser());
+		return $result[0]['account_id'];
+	}
+
+	protected function relatedRecordIds($module, $moduleLabel, $parentId = null) {
+		global $adb, $log;
+		$relatedIds = array();
+		$mode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+		if ($parentId == null) {
+			$contactWebserviceId = vtws_getWebserviceEntityId('Contacts', $this->getActiveCustomer()->id);
+			if ($mode == 'mine') {
+				$parentId = $contactWebserviceId;
+			} else {
+				if (in_array($module, array('Products', 'Services'))) {
+					$relatedIds = CustomerPortal_Utils::getAllRecordIds($module, $this->getActiveUser());
+					return $relatedIds;
+				} else {
+					$parentId = $this->getParent($contactWebserviceId);
+					if (empty($parentId)) {
+						$parentId = $contactWebserviceId;
+					}
+				}
+			}
+		}
+		$webserviceObject = VtigerWebserviceObject::fromId($adb, $parentId);
+		$handlerPath = $webserviceObject->getHandlerPath();
+		$handlerClass = $webserviceObject->getHandlerClass();
+		require_once $handlerPath;
+		$handler = new $handlerClass($webserviceObject, $this->getActiveUser(), $adb, $log);
+		$relatedIds = $handler->relatedIds($parentId, $module, $moduleLabel);
+		return $relatedIds;
+	}
+
+	protected function isRecordAccessible($recordId, $module = null, $moduleLabel = null) {
+		global $adb;
+
+		if (empty($module)) {
+			$module = VtigerWebserviceObject::fromId($adb, $recordId)->getEntityName();
+			$moduleLabel = CustomerPortal_Utils::getRelatedModuleLabel($module);
+		}
+
+		if (empty($moduleLabel)) {
+			$moduleLabel = CustomerPortal_Utils::getRelatedModuleLabel($module);
+		}
+		$mode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+		$relatedIds = $this->relatedRecordIds($module, $moduleLabel);
+		if (in_array($recordId, $relatedIds) || ($mode == 'all' && in_array($module, array('Products', 'Services')))) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	protected function isFaqPublished($recordId) {
+		$sql = sprintf('SELECT faqstatus FROM %s WHERE id=\'%s\';', 'Faq', $recordId);
+		$result = vtws_query($sql, $this->getActiveUser());
+		if ($result[0]['faqstatus'] == 'Published') {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/AddComment.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/AddComment.php
new file mode 100644
index 0000000000000000000000000000000000000000..4fd75a5a844bc451ba8eabe74e2c7ba7b6332c44
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/AddComment.php
@@ -0,0 +1,79 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+include_once dirname(__FILE__).'/SaveRecord.php';
+
+class CustomerPortal_AddComment extends CustomerPortal_SaveRecord {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		global $adb;
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$valuesJSONString = $request->get('values');
+			$element = null;
+
+			if (!empty($valuesJSONString) && is_string($valuesJSONString)) {
+				$element = Zend_Json::decode($valuesJSONString);
+			} else {
+				$element = $valuesJSONString; // Either empty or already decoded.
+			}
+
+			$element['assigned_user_id'] = vtws_getWebserviceEntityId('Users', $current_user->id);
+			$parentId = $request->get('parentId');
+
+			$relatedRecordId = $element['related_to'];
+			$relatedModule = VtigerWebserviceObject::fromId($adb, $relatedRecordId)->getEntityName();
+
+			if (!CustomerPortal_Utils::isModuleActive($relatedModule)) {
+				throw new Exception("Module not accessible.", 1412);
+				exit;
+			}
+
+			if (!empty($parentId)) {
+				if (!$this->isRecordAccessible($parentId)) {
+					throw new Exception("Parent record not accessible.", 1412);
+					exit;
+				}
+				$relatedRecordIds = $this->relatedRecordIds($relatedModule, CustomerPortal_Utils::getRelatedModuleLabel($relatedModule), $parentId);
+
+				if (!in_array($relatedRecordId, $relatedRecordIds)) {
+					throw new Exception("Record not Accessible", 1412);
+					exit;
+				}
+			} else {
+				//If module is Faq by pass this check as we Faq's are not related to Contacts module.
+				if ($relatedModule == 'Faq') {
+					if (!($this->isFaqPublished($relatedRecordId))) {
+						throw new Exception("This Faq is not published", 1412);
+						exit;
+					}
+				} else if (!$this->isRecordAccessible($relatedRecordId)) {
+					throw new Exception("Record not accessible.", 1412);
+					exit;
+				}
+			}
+			// Always set the customer to Portal user when comment is added from portal 
+			$customerId = vtws_getWebserviceEntityId('Contacts', $this->getActiveCustomer()->id);
+			$element['customer'] = $customerId;
+			$element['from_portal'] = true;
+			$element['commentcontent'] = nl2br($element['commentcontent']);
+			//comment_added_from_portal added to check workflow condition "is added from portal" for comments.
+			//Cannot use from_portal as Mailroom also sets to TRUE.
+			$element['comment_added_from_portal'] = true;
+			$result = vtws_create('ModComments', $element, $current_user);
+			$result = CustomerPortal_Utils::resolveRecordValues($result, $current_user);
+			$response->setResult($result);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ChangePassword.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ChangePassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae4dd5fc4e6686482031281bdc59cbc23c5db163
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ChangePassword.php
@@ -0,0 +1,36 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_ChangePassword extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		global $adb;
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$current_customer = $this->getActiveCustomer();
+			$username = $this->getActiveCustomer()->username;
+			$password = $request->get('password');
+
+			if (!$this->authenticatePortalUser($username, $password)) {
+				throw new Exception("Wrong password.Please try again", 1412);
+				exit;
+			}
+
+			$newPassword = $request->get('newPassword');
+			$sql = "UPDATE vtiger_portalinfo SET user_password=? WHERE id=? AND user_name=?";
+			$adb->pquery($sql, array(Vtiger_Functions::generateEncryptedPassword($newPassword), $current_customer->id, $username));
+			$response->setResult('Password changed successfully');
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DescribeModule.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DescribeModule.php
new file mode 100644
index 0000000000000000000000000000000000000000..055779852ebaa2e13cc8940b5125beea78b0e3a9
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DescribeModule.php
@@ -0,0 +1,78 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_DescribeModule extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$current_user = $this->getActiveUser();
+		$response = new CustomerPortal_API_Response();
+
+		if ($current_user) {
+			$module = $request->get('module');
+
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception('Module not accessible', 1412);
+				exit;
+			}
+
+			$describeInfo = vtws_describe($module, $current_user);
+			// Get active fields with read, write permissions
+			$activeFields = CustomerPortal_Utils::getActiveFields($module, true);
+			$activeFieldKeys = array_keys($activeFields);
+			foreach ($describeInfo['fields'] as $key => $value) {
+				if (!in_array($value['name'], $activeFieldKeys)) {
+					unset($describeInfo['fields'][$key]);
+				} else {
+					// Handling UTF-8 charecters in Picklist values
+					$value['default'] = decode_html($value['default']);
+					if ($value['type']['name'] === 'picklist' || $value['type']['name'] === 'metricpicklist') {
+						$pickList = $value['type']['picklistValues'];
+
+						foreach ($pickList as $pickListKey => $pickListValue) {
+							$pickListValue['label'] = decode_html(vtranslate($pickListValue['value'], $module));
+							$pickListValue['value'] = decode_html($pickListValue['value']);
+							$pickList[$pickListKey] = $pickListValue;
+						}
+						$value['type']['picklistValues'] = $pickList;
+					} else if ($value['type']['name'] === 'time') {
+						$value['default'] = Vtiger_Time_UIType::getTimeValueWithSeconds($value['default']);
+					}
+					$value['label'] = decode_html($value['label']);
+					if ($activeFields[$value['name']]) {
+						$value['editable'] = true;
+					} else {
+						$value['editable'] = false;
+					}
+					$describeInfo['fields'][$key] = $value;
+
+					$position = array_search($value['name'], $activeFieldKeys);
+					$fieldList[$position] = $describeInfo['fields'][$key];
+				}
+			}
+			if ($fieldList) {
+				unset($describeInfo['fields']);
+				$describeInfo['fields'] = $fieldList;
+			}
+
+			//Describe giving wrong labelfields for HelpDesk and Documents.
+			if ($module == 'Documents') {
+				$describeInfo['labelFields'] = 'notes_title';
+			}
+			if ($module == 'HelpDesk') {
+				$describeInfo['labelFields'] = 'ticket_title';
+			}
+
+			$describeInfo['label'] = decode_html(vtranslate($describeInfo['label'], $module));
+			$response->addToResult('describe', $describeInfo);
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DownloadFile.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DownloadFile.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8260dda8db6e8922a0d84fe144430c510e00b4b
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DownloadFile.php
@@ -0,0 +1,124 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_DownloadFile extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		global $adb;
+		$current_user = $this->getActiveUser();
+		$response = new CustomerPortal_API_Response();
+
+		if ($current_user) {
+			$parentId = $request->get('parentId');
+			$recordId = $request->get('recordId');
+			$module = $request->get('module');
+			$parentModule = $request->get('parentModule');
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				$response->setError(1404, 'Module is disabled.');
+				return $response;
+			}
+
+			if (!empty($parentId)) {
+				if ($parentModule === 'Faq') {
+					if (!($this->isFaqPublished($parentId))) {
+						throw new Exception("This Faq is not published", 1412);
+						exit;
+					}
+				} else {
+					if (!$this->isRecordAccessible($parentId)) {
+						throw new Exception("Parent record not Accessible", 1412);
+						exit;
+					}
+					$relatedRecordIds = $this->relatedRecordIds($module, CustomerPortal_Utils::getRelatedModuleLabel($module, $parentModule), $parentId);
+
+
+					if (!in_array($recordId, $relatedRecordIds)) {
+						throw new Exception("Record not Accessible", 1412);
+						exit;
+					}
+				}
+			} else {
+				if (!$this->isRecordAccessible($recordId, $module) && $module != 'ModComments') {
+					$response->setError(1404, 'Record not accessible');
+					return $response;
+				}
+			}
+			$idComponents = vtws_getIdComponents($recordId);
+			$id = $idComponents[1];
+			if ($module == 'Documents') {
+				$query = "SELECT filetype FROM vtiger_notes INNER JOIN vtiger_crmentity ON vtiger_notes.notesid= vtiger_crmentity.crmid 
+                          WHERE notesid =? AND vtiger_crmentity.deleted=?";
+				$res = $adb->pquery($query, array($id, '0'));
+				$filetype = $adb->query_result($res, 0, "filetype");
+				$this->updateDownloadCount($id);
+
+				$fileidQuery = 'SELECT attachmentsid FROM vtiger_seattachmentsrel WHERE crmid = ?';
+				$fileres = $adb->pquery($fileidQuery, array($id));
+				$fileid = $adb->query_result($fileres, 0, 'attachmentsid');
+
+				$filepathQuery = 'SELECT path,name FROM vtiger_attachments WHERE attachmentsid = ?';
+				$fileres = $adb->pquery($filepathQuery, array($fileid));
+				$filepath = $adb->query_result($fileres, 0, 'path');
+				$filename = $adb->query_result($fileres, 0, 'name');
+				$filename = decode_html($filename);
+
+				$saved_filename = $fileid."_".$filename;
+				$filenamewithpath = $filepath.$saved_filename;
+				$filesize = filesize($filenamewithpath);
+				$fileDetails = array();
+				$fileDetails['fileid'] = $fileid;
+				$fileDetails['filename'] = $filename;
+				$fileDetails['filetype'] = $filetype;
+				$fileDetails['filesize'] = $filesize;
+				$fileDetails['filecontents'] = base64_encode(file_get_contents($filenamewithpath));
+				$response->setResult($fileDetails);
+			} else if ($module == 'ModComments') {
+				$attachmentId = $request->get('attachmentId');
+				$modCommentsRecordModel = Vtiger_Record_Model::getInstanceById($id, $module);
+				$rawAttachmentDetails = $modCommentsRecordModel->getFileDetails($attachmentId);
+				//construct path for attachment and get file size and type details
+				$attachmentDetails = $rawAttachmentDetails[0];
+				$fileid = $attachmentDetails['attachmentsid'];
+				$filename = $attachmentDetails['name'];
+				$filepath = $attachmentDetails['path'];
+				$saved_filename = $fileid."_".$filename;
+				$filenamewithpath = $filepath.$saved_filename;
+				$filesize = filesize($filenamewithpath);
+				$filetype = $attachmentDetails['type'];
+
+				//Construct array with all attachment details
+				$fileDetails = array();
+				$fileDetails['fileid'] = $fileid;
+				$fileDetails['filename'] = $filename;
+				$fileDetails['filetype'] = $filetype;
+				$fileDetails['filesize'] = $filesize;
+				$fileDetails['filecontents'] = base64_encode(file_get_contents($filenamewithpath));
+				$response->setResult($fileDetails);
+			} else {
+				throw new Exception("Download not supported.", 1412);
+				exit;
+			}
+			return $response;
+		}
+	}
+
+	/**
+	 * Function to update the download count of a file
+	 */
+	function updateDownloadCount($id) {
+		global $adb, $log;
+		$log->debug("Entering customer portal function updateDownloadCount");
+		$updateDownloadCount = "UPDATE vtiger_notes SET filedownloadcount = filedownloadcount+1 WHERE notesid = ?";
+		$countres = $adb->pquery($updateDownloadCount, array($id));
+		$log->debug("Entering customer portal function updateDownloadCount");
+		return true;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ExportRecords.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ExportRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a6721e8161e49eaea1afad20ce3da3a6a75d197
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ExportRecords.php
@@ -0,0 +1,114 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_ExportRecords extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+		$db = PearDatabase::getInstance();
+		if ($current_user) {
+			$customerId = $this->getActiveCustomer()->id;
+			$contactWebserviceId = vtws_getWebserviceEntityId('Contacts', $customerId);
+			$accountId = $this->getParent($contactWebserviceId);
+			$mode = $request->get('mode');
+			$module = $request->get('module');
+			$fieldsArray = $request->get('fields');
+			$fieldsArray = Zend_Json::decode($fieldsArray);
+
+			//validate module with portal settings
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("Module not accessible", 1412);
+				exit;
+			}
+
+			//validate filter fields with portal settings
+			$activeFields = CustomerPortal_Utils::getActiveFields($module);
+			if ($fieldsArray !== null) {
+				foreach ($fieldsArray as $key => $value) {
+					if (!in_array($key, $activeFields)) {
+						throw new Exception($key." is not accessible.", 1412);
+						exit;
+					}
+				}
+			}
+
+			$fields = $fields = implode(',', $activeFields);
+			if (empty($mode)) {
+				$mode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+			}
+			if ($mode == 'all' && in_array($module, array('Products', 'Services'))) {
+				$countSql = sprintf('SELECT count(*) FROM %s;', $module);
+				$countResult = vtws_query($countSql, $current_user);
+				$count = $countResult[0]['count'];
+			} else {
+				//setting parentId based on mode
+				$parentId = null;
+				if ($mode == 'mine') {
+					$parentId = $contactWebserviceId;
+				} else if ($mode == 'all') {
+					if (!empty($accountId)) {
+						if (CustomerPortal_Settings_Utils::getDefaultMode($module) == 'all')
+							$parentId = $accountId;
+						else
+							$parentId = $contactWebserviceId;
+					}
+					else {
+						$parentId = $contactWebserviceId;
+					}
+				}
+				$groupConditionsBy = $request->get('groupConditions');
+				if (empty($groupConditionsBy))
+					$groupConditionsBy = 'AND';
+				$countSql = sprintf('SELECT count(*) FROM %s', $module);
+
+				if (!empty($fieldsArray)) {
+					$countSql = sprintf('SELECT count(*) FROM %s WHERE ', $module);
+					foreach ($fieldsArray as $key => $value) {
+						$countSql.= $key.'=\''.$value."' ".$groupConditionsBy." ";
+					}
+					$countSql = CustomerPortal_Utils::str_replace_last($groupConditionsBy, '', $countSql);
+				}
+				$moduleLabel = CustomerPortal_Utils::getRelatedModuleLabel($module);
+				$countResult = vtws_query_related($countSql, $parentId, $moduleLabel, $current_user);
+				$count = $countResult[0]['count'];
+			}
+			//vtws_query gives max of 100 records per request.loop for records if more than 100
+			$pageLimit = 100;
+			$loopCount = $count / $pageLimit;
+			$records = array();
+
+			for ($i = 0; $i < $loopCount; $i++) {
+				if (!empty($fieldsArray)) {
+					$sql = sprintf('SELECT %s FROM %s WHERE ', $fields, $module);
+					foreach ($fieldsArray as $key => $value) {
+						$sql.= $key.'=\''.$value."' ".$groupConditionsBy." ";
+					}
+					$sql = CustomerPortal_Utils::str_replace_last($groupConditionsBy, '', $sql);
+				} else {
+					$sql = sprintf('SELECT %s FROM %s', $fields, $module);
+				}
+				$filterClause = sprintf(" LIMIT %s,%s", $i * $pageLimit, $pageLimit);
+				if ($mode == 'all' && in_array($module, array('Products', 'Services'))) {
+					$result = vtws_query($sql.' '.$filterClause.';', $current_user);
+				} else {
+					$result = vtws_query_related($sql, $parentId, $moduleLabel, $current_user, $filterClause);
+				}
+				// process result
+				foreach ($result as $key => $recordValues) {
+					$records[] = CustomerPortal_Utils::resolveRecordValues($recordValues);
+				}
+			}
+			$response->setResult($records);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchAnnouncement.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchAnnouncement.php
new file mode 100644
index 0000000000000000000000000000000000000000..7b51128cf33efc8bce6a3a9db99d54018b8f2cfa
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchAnnouncement.php
@@ -0,0 +1,27 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchAnnouncement extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		global $adb;
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$sql = "SELECT announcement FROM vtiger_customerportal_settings LIMIT 1";
+			$result = $adb->pquery($sql, array());
+			$announcement = $adb->query_result($result, 0, 'announcement');
+			$response->setResult(array('announcement' => $announcement));
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchCompanyDetails.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchCompanyDetails.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c1ff50e1cfe7fd2de7484bdffb905284639cb89
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchCompanyDetails.php
@@ -0,0 +1,30 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchCompanyDetails extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$current_user = $this->getActiveUser();
+		$response = new CustomerPortal_API_Response();
+
+		if ($current_user) {
+			$company_id = vtws_getCompanyId();
+			$companyDetails = vtws_retrieve($company_id, $current_user);
+			$companyDetailsModel = new Settings_Vtiger_CompanyDetails_Model();
+			$companyDetailsModel->set('logoname', $companyDetails['logoname']);
+			$filePath = $companyDetailsModel->getLogoPath();
+			$imageInfo = getimagesize($filePath);
+			$companyDetails['mime'] = $imageInfo['mime'];
+			$response->setResult($companyDetails);
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchCompanyTitle.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchCompanyTitle.php
new file mode 100644
index 0000000000000000000000000000000000000000..b2e21e2cd7558c3b607292b8e5a7c4c802b88b4d
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchCompanyTitle.php
@@ -0,0 +1,25 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchCompanyTitle extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$current_user = $this->getActiveUser();
+		$response = new CustomerPortal_API_Response();
+
+		if ($current_user) {
+			$company_id = vtws_getCompanyId();
+			$companyDetails = vtws_retrieve($company_id, $current_user);
+			$response->setResult($companyDetails);
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchHistory.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchHistory.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f289b12b21d2d7be51876c6ba16a60352544f59
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchHistory.php
@@ -0,0 +1,226 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchHistory extends CustomerPortal_FetchRecord {
+
+	function process(CustomerPortal_API_Request $request) {
+		global $adb;
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+		$pageLimit = (int) $request->get('pageLimit');
+
+		if (empty($pageLimit))
+			$pageLimit = CustomerPortal_Config::$DEFAULT_PAGE_LIMIT;
+
+		if ($current_user) {
+			$module = $request->get('module');
+			$recordId = $request->get('record');
+
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("History not available for this module", 1412);
+				exit;
+			}
+
+			if (!ModTracker::isTrackingEnabledForModule($module)) {
+				throw new Exception("Module not tracked for changes.", 1412);
+				exit;
+			}
+
+			//Incase of ProjectTask and Milestones parent will be Project
+			$parentId = $request->get('parentId');
+			if (!empty($parentId)) {
+				if (!$this->isRecordAccessible($parentId)) {
+					throw new Exception("Parent record not accessible", 1412);
+					exit;
+				} else {
+					$relatedIds = $this->relatedRecordIds($module, CustomerPortal_Utils::getRelatedModuleLabel($module), $parentId);
+				}
+			} else {
+				$relatedIds = $this->relatedRecordIds($module, CustomerPortal_Utils::getRelatedModuleLabel($module));
+			}
+			if (empty($relatedIds)) {
+				throw new Exception("No records found", 1412);
+				exit;
+			}
+			$recordIds = array();
+
+			if (!empty($recordId)) {
+				if (!in_array($recordId, $relatedIds)) {
+					throw new Exception("Record not accessible", 1412);
+					exit;
+				}
+
+				$idComponents = explode("x", $recordId);
+				$recordIds[] = $idComponents[1];
+			} else {
+				foreach ($relatedIds as $id) {
+					$idComponents = explode("x", $id);
+					$recordIds[] = $idComponents[1];
+				}
+			}
+
+			$sql = 'SELECT vtiger_modtracker_basic.* FROM vtiger_modtracker_basic
+		            INNER JOIN vtiger_crmentity ON vtiger_modtracker_basic.crmid = vtiger_crmentity.crmid WHERE 
+                    vtiger_modtracker_basic.module = ? AND vtiger_crmentity.deleted = ? AND vtiger_modtracker_basic.crmid IN ('.generateQuestionMarks($recordIds).')
+                    ORDER BY changedon DESC';
+
+			$params = array();
+			$params[] = $module;
+			$params[] = '0';
+
+			foreach ($recordIds as $id) {
+				$params[] = $id;
+			}
+
+			$result = $adb->pquery($sql, $params);
+			$recordValuesMap = array();
+			$orderedIds = array();
+
+			while ($row = $adb->fetch_array($result)) {
+				$orderedIds[] = $row['id'];
+				$whodid = vtws_history_entityIdHelper('Users', $row['whodid']);
+				$crmid = vtws_history_entityIdHelper($module, $row['crmid']);
+				$status = $row['status'];
+
+				switch ($status) {
+					case ModTracker::$UPDATED: $statuslabel = 'updated';
+						break;
+					case ModTracker::$DELETED: $statuslabel = 'deleted';
+						break;
+					case ModTracker::$CREATED: $statuslabel = 'created';
+						break;
+					case ModTracker::$RESTORED: $statuslabel = 'restored';
+						break;
+					case ModTracker::$LINK: $statuslabel = 'link';
+						break;
+					case ModTracker::$UNLINK: $statuslabel = 'unlink';
+						break;
+				}
+
+				$item['modifieduser'] = $whodid;
+				$item['id'] = $crmid;
+				$item['modifiedtime'] = $row['changedon'];
+				$item['values'] = array();
+				$item['status'] = $statuslabel;
+
+				$recordValuesMap[$row['id']] = $item;
+			}
+
+			$historyItems = array();
+
+			if (!empty($orderedIds)) {
+				$activeFields = CustomerPortal_Utils::getActiveFields($module);
+				$sql = 'SELECT vtiger_modtracker_detail.* FROM vtiger_modtracker_detail';
+				$sql .= ' WHERE id IN ('.generateQuestionMarks($orderedIds).') AND 
+                          fieldname IN('.generateQuestionMarks($activeFields).') ORDER BY id DESC LIMIT ?,?';
+
+				$params = $orderedIds;
+				foreach ($activeFields as $field) {
+					$params[] = $field;
+				}
+				$page = $request->get('page');
+
+				if (empty($page)) {
+					$params[] = 0;
+				} else {
+					$params[] = $page * $pageLimit;
+				}
+				$params[] = $pageLimit;
+
+				$result = $adb->pquery($sql, $params);
+
+				while ($row = $adb->fetch_array($result)) {
+					$item = $recordValuesMap[$row['id']];
+
+					// NOTE: For reference field values transform them to webservice id.
+					$item['values'][$row['fieldname']] = array(
+						'previous' => decode_html($row['prevalue']),
+						'current' => decode_html($row['postvalue'])
+					);
+
+
+					$recordValuesMap[$row['id']] = $item;
+				}
+
+				// Group the values per basic-transaction
+				foreach ($orderedIds as $id) {
+					if (count($recordValuesMap[$id]['values']) > 0)
+						$historyItems[] = $recordValuesMap[$id];
+				}
+			}
+
+			if (!empty($historyItems))
+				$this->resolveReferences($historyItems, $module, $current_user);
+			$response->setResult(array('history' => $historyItems));
+		} else {
+			$response->setError(1404, "No permission to perform this operation.");
+		}
+		return $response;
+	}
+
+	protected function resolveReferences(&$items, $module, $user) {
+		$ids = array();
+
+		foreach ($items as $item) {
+			$ids[] = $item['id'];
+		}
+		$labels = Vtiger_Util_Helper::fetchRecordLabelsForIds($ids);
+		$describe = vtws_describe($module, $user);
+
+		foreach ($items as &$item) {
+			$modifiedUser = $this->fetchLabelForUserId($item['modifieduser'], $user);
+			$modifiedUser['label'] = decode_html($modifiedUser['label']);
+			$item['modifieduser'] = $modifiedUser;
+			$item['label'] = decode_html($labels[$item['id']]);
+			$values = $item['values'];
+
+
+
+			foreach ($values as $field => $value) {
+				if (CustomerPortal_Utils::isOwnerType($field, $describe)) {
+					$previous = $value['previous'];
+					$current = $value['current'];
+
+					if (!empty($previous)) {
+						$previousOwnerType = vtws_getOwnerType($previous);
+						$previousWSId = vtws_getWebserviceEntityId($previousOwnerType, $previous);
+						$value['previous'] = trim(vtws_getName($previousWSId, $user));
+					}
+
+					$currentOwnerType = vtws_getOwnerType($current);
+					$currentWSId = vtws_getWebserviceEntityId($currentOwnerType, $current);
+					$value['current'] = trim(vtws_getName($currentWSId, $user));
+				}
+
+				if (CustomerPortal_Utils::isReferenceType($field, $describe)) {
+					$previous = $value['previous'];
+					$current = $value['current'];
+
+					if (!empty($previous)) {
+						$value['previous'] = Vtiger_Util_Helper::getRecordName($previous, true);
+					}
+					$value['current'] = Vtiger_Util_Helper::getRecordName($current, true);
+				}
+
+				$value['previous'] = decode_html($value['previous']);
+				$value['current'] = decode_html($value['current']);
+				$values[$field] = $value;
+			}
+			$item['values'] = $values;
+			unset($item);
+		}
+	}
+
+	protected function fetchLabelForUserId($id, $user) {
+		$label = trim(vtws_getName($id, $user));
+		return array('value' => $id, 'label' => $label);
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchLabelFields.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchLabelFields.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c22b8192e088f79f759c521aa33c21a6ab3a925
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchLabelFields.php
@@ -0,0 +1,36 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchLabelFields extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$current_user = $this->getActiveUser();
+		$response = new CustomerPortal_API_Response();
+		global $adb;
+
+		if ($current_user) {
+			$sql = "SELECT tabid FROM vtiger_customerportal_tabs WHERE visible=? ";
+			$sqlResult = $adb->pquery($sql, array(1));
+			$num_rows = $adb->num_rows($sqlResult);
+			$result = array();
+
+			for ($i = 0; $i < $num_rows; $i++) {
+				$moduleId = $adb->query_result($sqlResult, $i, 'tabid');
+				$module = Vtiger_Functions::getModuleName($moduleId);
+				$describe = vtws_describe($module, $current_user);
+				$labelFields = explode(',', $describe['labelFields']);
+				$result[] = array($module => $labelFields);
+			}
+		}
+		$response->setResult($result);
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchModules.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchModules.php
new file mode 100644
index 0000000000000000000000000000000000000000..039d16d0a960121b977235e785474d6c7b9341a4
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchModules.php
@@ -0,0 +1,63 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchModules extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$current_user = $this->getActiveUser();
+		$response = new CustomerPortal_API_Response();
+		global $adb;
+
+		if ($current_user) {
+			$result = array();
+			$customerId = vtws_getWebserviceEntityId('Contacts', $this->getActiveCustomer()->id);
+			$accountId = $this->getParent($customerId);
+			$user_id = CustomerPortal_Settings_Utils::getDefaultAssignee();
+			$result['contact_id'] = array('value' => $customerId, 'label' => Vtiger_Util_Helper::fetchRecordLabelForId($customerId));
+
+			if (!empty($accountId)) {
+				$result['account_id'] = array('value' => $accountId, 'label' => Vtiger_Util_Helper::fetchRecordLabelForId($accountId));
+			}
+
+			$result['user_id'] = array('value' => $user_id, 'label' => decode_html(trim(vtws_getName($user_id, $current_user))));
+			$sql = "SELECT vtiger_relatedlists.label, vtiger_customerportal_tabs.tabid, vtiger_customerportal_tabs.sequence,
+                    vtiger_customerportal_tabs.createrecord,vtiger_customerportal_tabs.editrecord,vtiger_customerportal_fields.records_visible 
+                    FROM vtiger_customerportal_tabs INNER JOIN vtiger_tab on vtiger_tab.tabid = vtiger_customerportal_tabs.tabid 
+                    and vtiger_tab.presence=? INNER JOIN vtiger_relatedlists ON vtiger_customerportal_tabs.tabid =vtiger_relatedlists.related_tabid 
+                    INNER JOIN vtiger_customerportal_fields ON vtiger_customerportal_fields.tabid = vtiger_customerportal_tabs.tabid WHERE   
+                    vtiger_customerportal_tabs.visible =? GROUP BY vtiger_customerportal_tabs.tabid ORDER BY vtiger_customerportal_tabs.sequence ASC;";
+			$sqlResult = $adb->pquery($sql, array(0, 1));
+			$num_rows = $adb->num_rows($sqlResult);
+
+			$modules = array('types' => array(), 'information' => array());
+			for ($i = 0; $i < $num_rows; $i++) {
+				$moduleId = $adb->query_result($sqlResult, $i, 'tabid');
+				$moduleName = Vtiger_Functions::getModuleName($moduleId);
+				if (!Vtiger_Runtime::isRestricted('modules', $moduleName)) {
+					$modules['types'][] = $moduleName;
+					$modules['information'][$moduleName] = array(
+						'name' => $moduleName,
+						'label' => $adb->query_result($sqlResult, $i, 'label'),
+						'uiLabel' => decode_html(vtranslate($moduleName, $moduleName)),
+						'order' => $adb->query_result($sqlResult, $i, 'sequence'),
+						'create' => $adb->query_result($sqlResult, $i, 'createrecord'),
+						'edit' => $adb->query_result($sqlResult, $i, 'editrecord'),
+						'recordvisibility' => $adb->query_result($sqlResult, $i, 'records_visible')
+					);
+				}
+			}
+
+			$result['modules'] = $modules;
+			$response->setResult($result);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchProfile.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchProfile.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9535a12228bd017d2fe99f1f98b30bfd78c1d2b
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchProfile.php
@@ -0,0 +1,41 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchProfile extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$contactId = vtws_getWebserviceEntityId('Contacts', $this->getActiveCustomer()->id);
+			$encodedContactImage = CustomerPortal_Utils::getImageDetails($this->getActiveCustomer()->id, 'Contacts');
+			$accountId = $this->getParent($contactId);
+
+			$contact = vtws_retrieve($contactId, $current_user);
+			$contact = CustomerPortal_Utils::resolveRecordValues($contact);
+			$contact['imagedata'] = $encodedContactImage['imagedata'];
+			$contact['imagetype'] = $encodedContactImage['imagetype'];
+			$response->addToResult('customer_details', $contact);
+
+			if (!empty($accountId)) {
+				$idComponents = explode('x', $accountId);
+				$encodedAccountImage = CustomerPortal_Utils::getImageDetails($idComponents[1], 'Accounts');
+				$account = vtws_retrieve($accountId, $current_user);
+				$account = CustomerPortal_Utils::resolveRecordValues($account);
+				$account['imagedata'] = $encodedAccountImage['imagedata'];
+				$account['imagetype'] = $encodedAccountImage['imagetype'];
+				$response->addToResult('company_details', $account);
+			}
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecentRecords.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecentRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..dbceef6076b5143ece48103786e53ef18d90352d
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecentRecords.php
@@ -0,0 +1,111 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchRecentRecords extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+		global $adb;
+
+		if ($current_user) {
+			$sql = "SELECT widgets FROM vtiger_customerportal_settings LIMIT 1";
+			$result = $adb->pquery($sql, array());
+			$widgetsJSON = $adb->query_result($result, 0, 'widgets');
+			$data = array();
+			$data = Zend_Json::decode(decode_html($widgetsJSON));
+			$widgets = $data['widgets'];
+			$activeModules = array();
+
+			foreach ($widgets as $key => $value) {
+				if (CustomerPortal_Utils::isModuleActive($key) && $value == '1')
+					$activeModules[] = $key;
+			}
+			$result = array();
+			$customerId = $this->getActiveCustomer()->id;
+			$contactWebserviceId = vtws_getWebserviceEntityId('Contacts', $customerId);
+
+			foreach ($activeModules as $module) {
+				$mode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+
+				if ($mode === 'all') {
+					$parentId = $this->getParent($contactWebserviceId);
+					if (empty($parentId)) {
+						$parentId = $contactWebserviceId;
+					}
+				} else {
+					$parentId = $contactWebserviceId;
+				}
+				$limit = 5;
+				$sql = sprintf("SELECT id FROM %s ", $module);
+				$filterClause = sprintf('ORDER BY modifiedtime DESC LIMIT %s', $limit);
+
+				if ($module == 'Faq') {
+					$queryResult = vtws_query($sql . "WHERE faqstatus='Published' " . $filterClause . ';', $current_user);
+				} else if ($module == 'HelpDesk') {
+					$fields = array("ticketstatus", "description");
+					$moduleModel = Vtiger_Module_Model::getInstance($module);
+					$allowedFields = array();
+
+					foreach ($fields as $field) {
+						$fieldModel = Vtiger_Field_Model::getInstance($field, $moduleModel);
+						if ($fieldModel->isActiveField()) {
+							$allowedFields[] = $field;
+						}
+					}
+
+					if (!empty($allowedFields)) {
+						$fieldsSql = implode(",", $allowedFields);
+						$sql = sprintf("SELECT id, %s FROM %s", $fieldsSql, $module);
+					}
+					$queryResult = vtws_query_related($sql, $parentId, CustomerPortal_Utils::getRelatedModuleLabel($module), $current_user, $filterClause);
+				} else if ($mode == 'all' && in_array($module, array('Products', 'Services'))) {
+					$sql = sprintf("SELECT id FROM %s", $module);
+					$filterClause = sprintf("ORDER BY modifiedtime DESC LIMIT %s;", $limit);
+					$queryResult = vtws_query($sql . ' ' . $filterClause, $current_user);
+				} else {
+					$queryResult = vtws_query_related($sql, $parentId, CustomerPortal_Utils::getRelatedModuleLabel($module), $current_user, $filterClause);
+				}
+				$num_rows = sizeof($queryResult);
+				$records = array();
+				$recordIds = array();
+
+				if (!empty($queryResult)) {
+					foreach ($queryResult as $resultRecord) {
+						$recordIds[] = $resultRecord['id'];
+					}
+					$recordLabels = Vtiger_Util_Helper::fetchRecordLabelsForIds($recordIds);
+					for ($i = 0; $i < $num_rows; $i++) {
+						$record = array();
+						$id = $recordIds[$i];
+						foreach ($recordLabels as $key => $value) {
+							if ($key == $id) {
+								$record['label'] = decode_html($value);
+								break;
+							}
+						}
+
+						if ($module == 'HelpDesk') {
+							$record['status'] = $queryResult[$i]['ticketstatus'];
+							$record['statuslabel'] = decode_html(vtranslate($queryResult[$i]['ticketstatus'], $module));
+							$record['description'] = decode_html($queryResult[$i]['description']);
+						}
+						$record['id'] = $id;
+						$records[] = $record;
+					}
+				}
+				$result[] = array($module => $records);
+			}
+			$response->setResult($result);
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecord.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecord.php
new file mode 100644
index 0000000000000000000000000000000000000000..32206904d54c6cd97c990a992d9dacde8f0cc56e
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecord.php
@@ -0,0 +1,61 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchRecord extends CustomerPortal_API_Abstract {
+
+	protected function processRetrieve(CustomerPortal_API_Request $request) {
+		global $adb;
+		$parentId = $request->get('parentId');
+		$recordId = $request->get('recordId');
+		$module = VtigerWebserviceObject::fromId($adb, $recordId)->getEntityName();
+
+		if (!CustomerPortal_Utils::isModuleActive($module)) {
+			throw new Exception("Records not Accessible for this module", 1412);
+			exit;
+		}
+
+		if (!empty($parentId)) {
+			if (!$this->isRecordAccessible($parentId)) {
+				throw new Exception("Parent record not Accessible", 1412);
+				exit;
+			}
+			$relatedRecordIds = $this->relatedRecordIds($module, CustomerPortal_Utils::getRelatedModuleLabel($module), $parentId);
+
+			if (!in_array($recordId, $relatedRecordIds)) {
+				throw new Exception("Record not Accessible", 1412);
+				exit;
+			}
+		} else {
+			if (!$this->isRecordAccessible($recordId, $module)) {
+				throw new Exception("Record not Accessible", 1412);
+				exit;
+			}
+		}
+
+		$fields = implode(',', CustomerPortal_Utils::getActiveFields($module));
+		$sql = sprintf('SELECT %s FROM %s WHERE id=\'%s\';', $fields, $module, $recordId);
+		$result = vtws_query($sql, $this->getActiveUser());
+		return $result[0];
+	}
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$record = $this->processRetrieve($request);
+
+			$record = CustomerPortal_Utils::resolveRecordValues($record);
+			$response->setResult(array('record' => $record));
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecords.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..931c68d56638faa5991bb6b7e5d299ee033f9cd4
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRecords.php
@@ -0,0 +1,169 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchRecords extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$customerId = $this->getActiveCustomer()->id;
+			$contactWebserviceId = vtws_getWebserviceEntityId('Contacts', $customerId);
+			$accountId = $this->getParent($contactWebserviceId);
+			$mode = $request->get('mode');
+			$module = $request->get('module');
+			$moduleLabel = $request->get('moduleLabel');
+			$fieldsArray = $request->get('fields');
+			$orderBy = $request->get('orderBy');
+			$order = $request->get('order');
+			$activeFields = CustomerPortal_Utils::getActiveFields($module);
+
+			if (empty($orderBy)) {
+				$orderBy = 'modifiedtime';
+			} else {
+				if (!in_array($orderBy, $activeFields)) {
+					throw new Exception("sort by $orderBy not allowed", 1412);
+					exit;
+				}
+			}
+
+			if (empty($order)) {
+				$order = 'DESC';
+			} else {
+				if (!in_array(strtoupper($order), array("DESC", "ASC"))) {
+					throw new Exception("Invalid sorting order", 1412);
+					exit;
+				}
+			}
+			$fieldsArray = Zend_Json::decode($fieldsArray);
+			$groupConditionsBy = $request->get('groupConditions');
+			$page = $request->get('page');
+			if (empty($page))
+				$page = 0;
+
+			$pageLimit = $request->get('pageLimit');
+
+			if (empty($pageLimit))
+				$pageLimit = CustomerPortal_Config::$DEFAULT_PAGE_LIMIT;
+
+			if (empty($groupConditionsBy))
+				$groupConditionsBy = 'AND';
+
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("Module not accessible", 1412);
+				exit;
+			}
+
+			if (empty($mode)) {
+				$mode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+			}
+			$count = null;
+
+			if ($fieldsArray !== null) {
+				foreach ($fieldsArray as $key => $value) {
+					if (!in_array($key, $activeFields)) {
+						throw new Exception($key." is not accessible.", 1412);
+						exit;
+					}
+				}
+			}
+			$fields = implode(',', $activeFields);
+
+			if ($module == 'Faq') {
+				if (!empty($fieldsArray)) {
+					$countSql = "SELECT COUNT(*) FROM Faq WHERE faqstatus='Published' AND ";
+					$sql = sprintf('SELECT %s FROM Faq WHERE faqstatus=\'Published\' AND ', $fields);
+
+					foreach ($fieldsArray as $key => $value) {
+						$countSql.= $key.'=\''.$value."' ".$groupConditionsBy." ";
+						$sql.= $key.'=\''.$value."' ".$groupConditionsBy." ";
+					}
+					$countSql = CustomerPortal_Utils::str_replace_last($groupConditionsBy, ';', $countSql);
+					$sql = CustomerPortal_Utils::str_replace_last($groupConditionsBy, '', $sql);
+				} else {
+					$countSql = "SELECT COUNT(*) FROM Faq WHERE faqstatus='Published';";
+					$sql = sprintf('SELECT %s FROM Faq WHERE faqstatus=\'Published\'', $fields);
+				}
+				$countResult = vtws_query($countSql, $current_user);
+				$count = $countResult[0]['count'];
+
+				$sql = sprintf('%s ORDER BY %s %s LIMIT %s,%s ;', $sql, $orderBy, $order, ($page * $pageLimit), $pageLimit);
+				$result = vtws_query($sql, $current_user);
+			} else if ($module == 'Contacts') {
+				$result = vtws_query(sprintf("SELECT %s FROM %s WHERE id='%s';", $fields, $module, $contactWebserviceId), $current_user);
+			} else if ($module == 'Accounts') {
+				if (!empty($accountId))
+					$result = vtws_query(sprintf("SELECT %s FROM %s WHERE id='%s';", $fields, $module, $accountId), $current_user);
+			} else {
+				$relatedId = null;
+				$defaultMode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+				if (!empty($fieldsArray)) {
+					$countSql = sprintf('SELECT count(*) FROM %s WHERE ', $module);
+					$sql = sprintf('SELECT %s FROM %s WHERE ', $fields, $module);
+
+					foreach ($fieldsArray as $key => $value) {
+						$countSql.= $key.'=\''.$value."' ".$groupConditionsBy." ";
+						$sql.= $key.'=\''.$value."' ".$groupConditionsBy." ";
+					}
+
+					$countSql = CustomerPortal_Utils::str_replace_last($groupConditionsBy, '', $countSql);
+					$sql = CustomerPortal_Utils::str_replace_last($groupConditionsBy, '', $sql);
+				} else {
+					$countSql = sprintf('SELECT count(*) FROM %s', $module);
+					$sql = sprintf('SELECT %s FROM %s', $fields, $module);
+				}
+				if ($mode == 'mine') {
+					$relatedId = $contactWebserviceId;
+					$countResult = vtws_query_related($countSql, $relatedId, $moduleLabel, $current_user);
+					$count = $countResult[0]['count'];
+
+					$limitClause = sprintf('ORDER BY %s %s LIMIT %s,%s', $orderBy, $order, ($page * $pageLimit), $pageLimit);
+					$result = vtws_query_related($sql, $relatedId, $moduleLabel, $current_user, $limitClause);
+				} else if ($mode == 'all') {
+					if (in_array($module, array('Products', 'Services'))) {
+						$countSql = sprintf('SELECT count(*) FROM %s;', $module);
+						$sql = sprintf('SELECT %s FROM %s', $fields, $module);
+						$limitClause = sprintf('ORDER BY %s %s LIMIT %s,%s;', $orderBy, $order, ($page * $pageLimit), $pageLimit);
+						$sql = $sql.' '.$limitClause;
+						$result = vtws_query($sql, $current_user);
+						$countResult = vtws_query($countSql, $current_user);
+						$count = $countResult[0]['count'];
+					} else {
+						if (!empty($accountId)) {
+							if ($defaultMode == 'all')
+								$relatedId = $accountId;
+							else
+								$relatedId = $contactWebserviceId;
+						}
+						else {
+							$relatedId = $contactWebserviceId;
+						}
+
+						$countResult = vtws_query_related($countSql, $relatedId, $moduleLabel, $current_user);
+						$count = $countResult[0]['count'];
+
+						$limitClause = sprintf('ORDER BY %s %s LIMIT %s,%s', $orderBy, $order, ($page * $pageLimit), $pageLimit);
+						$result = vtws_query_related($sql, $relatedId, $moduleLabel, $current_user, $limitClause);
+					}
+				}
+			}
+
+			foreach ($result as $key => $recordValues) {
+				$result[$key] = CustomerPortal_Utils::resolveRecordValues($recordValues);
+			}
+
+			$response->setResult($result);
+			$response->addToResult('count', $count);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchReferenceRecords.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchReferenceRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..d3e0e750d18b00bd337abc2253230a18c97d2094
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchReferenceRecords.php
@@ -0,0 +1,81 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchReferenceRecords extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$customerId = $this->getActiveCustomer()->id;
+			$contactWebserviceId = vtws_getWebserviceEntityId('Contacts', $customerId);
+			$module = $request->get('module');
+			$searchKey = $request->get('searchKey');
+
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("Module not accessible", 1412);
+				exit;
+			}
+
+			$describe = vtws_describe($module, $current_user);
+			$labelFields = $describe['labelFields'];
+			//Describe giving wrong labels for HelpDesk and Documents.
+			if ($module == 'Documents') {
+				$labelFields = 'notes_title';
+			}
+			if ($module == 'HelpDesk') {
+				$labelFields = 'ticket_title';
+			}
+			$sql = sprintf("SELECT %s FROM %s ", $labelFields, $module);
+			$labelFieldsArray = explode(',', $labelFields);
+
+			if (!empty($searchKey)) {
+				$sql .= "WHERE ";
+				foreach ($labelFieldsArray as $labelField) {
+					$sql .= $labelField . " LIKE '%" . $searchKey . "%' OR ";
+				}
+				$sql = rtrim($sql, ' OR ');
+			}
+			$accountId = $this->getParent($contactWebserviceId);
+			$mode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+			$relatedId = null;
+			$referenceRecords = array();
+			if ($mode == 'mine') {
+				$relatedId = $contactWebserviceId;
+				$result = vtws_query_related($sql, $relatedId, CustomerPortal_Utils::getRelatedModuleLabel($module), $current_user);
+			} else if ($mode == 'all') {
+				if (in_array($module, array('Products', 'Services'))) {
+					$sql = $sql . ';';
+					$result = vtws_query($sql, $current_user);
+				} else {
+					if (!empty($accountId)) {
+						$relatedId = $accountId;
+					} else {
+						$relatedId = $contactWebserviceId;
+					}
+					$result = vtws_query_related($sql, $relatedId, CustomerPortal_Utils::getRelatedModuleLabel($module), $current_user);
+				}
+			}
+
+			foreach ($result as $value) {
+				$record = array();
+				foreach ($labelFieldsArray as $labelField) {
+					$record['label'].= ' ' . decode_html($value[$labelField]);
+					$record['id'] = decode_html($value['id']);
+				}
+				$referenceRecords[] = $record;
+			}
+			$response->setResult($referenceRecords);
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRelatedModules.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRelatedModules.php
new file mode 100644
index 0000000000000000000000000000000000000000..48e11360723362cb1fa95a95b3de34492a4336cb
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRelatedModules.php
@@ -0,0 +1,44 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchRelatedModules extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$current_user = $this->getActiveUser();
+		$response = new CustomerPortal_API_Response();
+
+		if ($current_user) {
+			$module = $request->get("module");
+
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("Module not accessible", 1412);
+				exit;
+			}
+			global $adb;
+			$sql = "SELECT  vtiger_customerportal_relatedmoduleinfo.relatedmodules FROM  vtiger_customerportal_relatedmoduleinfo 
+                    INNER JOIN vtiger_tab ON  vtiger_customerportal_relatedmoduleinfo.tabid = vtiger_tab.tabid 
+                    WHERE vtiger_tab.name= ?";
+			$result = $adb->pquery($sql, array($module));
+			if ($adb->num_rows($result) > 0) {
+				$relatedModulesJSON = $adb->query_result($result, 0, 'relatedmodules');
+				$data = Zend_Json::decode(decode_html($relatedModulesJSON));
+				$relatedModules = array();
+				foreach ($data as $module) {
+					if ($module["value"] == 1 && CustomerPortal_Utils::isModuleActive($module["name"])) {
+						$relatedModules[] = $module["name"];
+					}
+				}
+				$response->setResult($relatedModules);
+			}
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRelatedRecords.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRelatedRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..3043d9cc21ccfda72329b21ab064e5127f3c103b
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchRelatedRecords.php
@@ -0,0 +1,136 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchRelatedRecords extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		global $adb;
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$recordId = $request->get('recordId');
+			$parentId = $request->get('parentId');
+			$parentModule = $request->get('module');
+			$module = $request->get('relatedModule');
+			$moduleLabel = $request->get('relatedModuleLabel');
+			$page = $request->get('page');
+			$pageLimit = $request->get('pageLimit');
+			$mode = CustomerPortal_Settings_Utils::getDefaultMode($moduleLabel);
+			if (empty($pageLimit))
+				$pageLimit = CustomerPortal_Config::$DEFAULT_PAGE_LIMIT;
+
+			if (empty($page)) {
+				$page = 0;
+			}
+
+			if ($module != 'ModComments' && !CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("Module not Accessible", 1412);
+				exit;
+			}
+
+			if (!empty($parentId)) {
+				if (!$this->isRecordAccessible($parentId)) {
+					throw new Exception("Parent record not accessible", 1412);
+					exit;
+				}
+				$baseModule = VtigerWebserviceObject::fromId($adb, $recordId)->getEntityName();
+				$relatedRecordIds = $this->relatedRecordIds($baseModule, CustomerPortal_Utils::getRelatedModuleLabel($baseModule), $parentId);
+
+				if (!in_array($recordId, $relatedRecordIds)) {
+					throw new Exception("Record not Accessible", 1412);
+					exit;
+				}
+			} else if ($parentModule !== 'Faq') {
+				if (!$this->isRecordAccessible($recordId) && $prentModule !== 'Faq') {
+					throw new Exception("Record not accessible", 1412);
+					exit;
+				}
+			} else {
+				//If module is Faq by pass this check as we Faq's are not related to Contacts module.
+				if (!$this->isFaqPublished($recordId)) {
+					throw new Exception("This Faq is not published", 1412);
+					exit;
+				}
+			}
+
+			if ($module == 'ModComments' && !empty($recordId)) {
+				global $adb;
+				$relatedModule = VtigerWebserviceObject::fromId($adb, $recordId)->getEntityName();
+
+				if (!CustomerPortal_Utils::isModuleActive($relatedModule)) {
+					throw new Exception("Comments not accessible for this record", 1412);
+					exit;
+				}
+				$result = vtws_query(sprintf("SELECT * FROM ModComments WHERE related_to = '%s' AND is_private='%s' ORDER BY %s DESC LIMIT %s,%s;", $recordId, 0, 'modifiedtime', ($page * $pageLimit), $pageLimit), $current_user);
+
+				$fileIds = array();
+				$$relatedEmailIds = array();
+				if (is_array($result)) {
+					foreach ($result as $index => $value) {
+						$fileId = $value['filename'];
+						$attachmentIds = explode(',', $fileId);
+						//Fetching all attachments and its properties and appending to each comment.
+						if (!empty($attachmentIds)) {
+							$attachmentsResult = $adb->pquery('SELECT attachmentsid,name FROM vtiger_attachments WHERE attachmentsid IN ('.generateQuestionMarks($attachmentIds).')', $attachmentIds);
+							$result[$index]['attachments'] = array();
+							$noOfAttachments = $adb->num_rows($attachmentsResult);
+							$attachments = array();
+							for ($i = 0; $i < $noOfAttachments; $i++) {
+								$attachments[$i]['filename'] = decode_html($adb->query_result($attachmentsResult, $i, 'name'));
+								$attachments[$i]['attachmentid'] = $adb->query_result($attachmentsResult, $i, 'attachmentsid');
+							}
+						}
+						$result[$index]['attachments'] = $attachments;
+						$relatedEmailId = $value['related_email_id'];
+						if (!empty($relatedEmailId)) {
+							$relatedEmailIds[$value['id']] = $relatedEmailId;
+						}
+						if ($value['commentcontent']) {
+							$result[$index]['commentcontent'] = trim(decode_html(strip_tags($value['commentcontent'])));
+						}
+					}
+				}
+				if (!empty($relatedEmailIds)) {
+					foreach ($relatedEmailIds as $id => $emailId) {
+						$attachmentsResult = $adb->pquery('SELECT * FROM vtiger_attachments
+                            INNER JOIN vtiger_seattachmentsrel ON vtiger_attachments.attachmentsid = vtiger_seattachmentsrel.attachmentsid
+                            WHERE vtiger_seattachmentsrel.crmid = ?', array($emailId));
+						if ($row = $adb->fetch_row($attachmentsResult)) {
+							foreach ($result as $index => $value) {
+								if ($id == $value['id'])
+									$result[$index]['attachmentName'] = decode_html($row['name']);
+							}
+						}
+					}
+				}
+			} else {
+				$activeFields = CustomerPortal_Utils::getActiveFields($module);
+				$fields = implode(',', $activeFields);
+				$limitCaluse = sprintf('ORDER BY modifiedtime DESC LIMIT %s,%s', ($page * $pageLimit), $pageLimit);
+				if ($mode == 'all' && in_array($module, array('Products', 'Services'))) {
+					$sql = sprintf("SELECT %s FROM %s", $fields, $module);
+					$sql = $sql.' '.$limitCaluse;
+					$result = vtws_query($sql, $current_user);
+				} else {
+					$result = vtws_query_related(sprintf("SELECT %s FROM %s", $fields, $module), $recordId, $moduleLabel, $current_user, $limitCaluse);
+				}
+			}
+
+			foreach ($result as $key => $recordValues) {
+				$result[$key] = CustomerPortal_Utils::resolveRecordValues($recordValues);
+			}
+
+			$response->setResult($result);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchShortcuts.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchShortcuts.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee29fb31985b4638a1cc0fb3f0c7b039aa68c46c
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FetchShortcuts.php
@@ -0,0 +1,55 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FetchShortcuts extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		global $adb;
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$shortcuts = array();
+			$sql = "SELECT shortcuts FROM vtiger_customerportal_settings LIMIT 1";
+			$result = $adb->pquery($sql, array());
+			$shortcutsJSON = $adb->query_result($result, 0, 'shortcuts');
+			$data = Zend_Json::decode(decode_html($shortcutsJSON));
+
+			foreach ($data as $module => $value) {
+				$operations = array();
+				if (is_array($value)) {
+					foreach ($value as $key1 => $value1) {
+						if ($value1 != 0)
+							$operations[] = $key1;
+					}
+
+					if (!empty($operations) && CustomerPortal_Utils::isModuleActive($module)) {
+						$shortcuts[] = array($module => $operations);
+					}
+				}
+			}
+			$isHelpDeskRecordCreatable = CustomerPortal_Utils::isModuleRecordCreatable('HelpDesk');
+			foreach ($shortcuts as $shortcutArray => $shortcutValues) {
+				foreach ($shortcutValues as $module => $values) {
+					if ($module == 'HelpDesk' && !$isHelpDeskRecordCreatable) {
+						$createShortCutKey = array_search('LBL_CREATE_TICKET', $values);
+						unset($values[$createShortCutKey]);
+						$values = array_values($values);
+						$shortcutValues['HelpDesk'] = $values;
+						$shortcuts[$shortcutArray] = $shortcutValues;
+					}
+				}
+			}
+			$response->setResult(array('shortcuts' => $shortcuts));
+		}
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FilterRecords.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FilterRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..da68109252403df19acbb8ec1fb0d3a14ccf19eb
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/FilterRecords.php
@@ -0,0 +1,74 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_FilterRecords extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$customerId = $this->getActiveCustomer()->id;
+			$contactWebserviceId = vtws_getWebserviceEntityId('Contacts', $customerId);
+			$module = $request->get('module');
+
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("Module not accessible", 1412);
+				exit;
+			}
+
+			$moduleLabel = $request->get('moduleLabel');
+			$mode = CustomerPortal_Settings_Utils::getDefaultMode($module);
+			$orderByfield = $request->get('field');
+			$order = $request->get('orderBy');
+			$limit = $request->get('limit');
+
+			if (empty($limit))
+				$limit = CustomerPortal_Config::$DEFAULT_PAGE_LIMIT;
+
+			$activeFields = CustomerPortal_Utils::getActiveFields($module);
+
+			if (!empty($orderByfield) && !in_array($orderByfield, $activeFields)) {
+				throw new Exception("filter by field not accessible", 1412);
+				exit;
+			}
+
+			$fields = implode(',', $activeFields);
+			$relatedId = $contactWebserviceId;
+
+			if ($mode == 'all') {
+				$accountId = $this->getParent($contactWebserviceId);
+				if (!empty($accountId))
+					$relatedId = $accountId;
+			}
+
+			$sql = sprintf("SELECT %s FROM %s", $fields, $module);
+			$filterClause = null;
+
+			if (!empty($orderByfield) && !empty($order)) {
+				$filterClause.= ' ORDER BY '.$orderByfield." ".$order;
+			}
+
+			if (!empty($limit)) {
+				$filterClause.= ' LIMIT '.$limit;
+			}
+
+			$result = vtws_query_related($sql, $relatedId, $moduleLabel, $this->getActiveUser(), $filterClause);
+
+			foreach ($result as $key => $recordValues) {
+				$result[$key] = CustomerPortal_Utils::resolveRecordValues($recordValues);
+			}
+
+			$response->setResult($result);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ForgotPassword.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ForgotPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad8ce5a8dc309c33cee9692e5cd1dc9ca2e2c5f3
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/ForgotPassword.php
@@ -0,0 +1,96 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_ForgotPassword extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		global $adb, $PORTAL_URL, $current_user;
+		$userId = $this->getCurrentPortalUser();
+		$user = new Users();
+		$current_user = $user->retrieveCurrentUserInfoFromFile($userId);
+
+		$response = new CustomerPortal_API_Response();
+		$mailid = $request->get('email');
+		$current_date = date("Y-m-d");
+		$sql = 'SELECT * FROM vtiger_portalinfo
+					INNER JOIN vtiger_contactdetails ON vtiger_contactdetails.contactid=vtiger_portalinfo.id
+					INNER JOIN vtiger_customerdetails ON vtiger_customerdetails.customerid=vtiger_portalinfo.id
+					INNER JOIN vtiger_crmentity ON vtiger_portalinfo.id=vtiger_crmentity.crmid 
+						WHERE vtiger_portalinfo.user_name = ? AND vtiger_crmentity.deleted= ?
+						AND vtiger_customerdetails.support_start_date <= ?';
+
+		$res = $adb->pquery($sql, array($mailid, '0', $current_date));
+		$num_rows = $adb->num_rows($res);
+
+		if ($num_rows > 0) {
+			$isActive = $adb->query_result($res, 0, 'isactive');
+			$support_end_date = $adb->query_result($res, 0, 'support_end_date');
+
+			if ($isActive && ($support_end_date >= $current_date || $support_end_date == null )) {
+				$moduleName = 'Contacts';
+				global $HELPDESK_SUPPORT_EMAIL_ID, $HELPDESK_SUPPORT_NAME;
+				$user_name = $adb->query_result($res, 0, 'user_name');
+				$contactId = $adb->query_result($res, 0, 'id');
+
+				if (!empty($adb->query_result($res, 0, 'cryptmode'))) {
+					$password = makeRandomPassword();
+					$enc_password = Vtiger_Functions::generateEncryptedPassword($password);
+
+					$sql = 'UPDATE vtiger_portalinfo SET user_password=?, cryptmode=? WHERE id=?';
+					$params = array($enc_password, 'CRYPT', $contactId);
+					$adb->pquery($sql, $params);
+				}
+
+				$portalURL = vtranslate('Please ', $moduleName).'<a href="'.$PORTAL_URL.'" style="font-family:Arial, Helvetica, sans-serif;font-size:13px;">'.vtranslate('click here', $moduleName).'</a>';
+				$contents = '<table><tr><td>
+								<strong>Dear '.$adb->query_result($res, 0, 'firstname')." ".$adb->query_result($res, 0, 'lastname').'</strong><br></td></tr><tr>
+								<td>'.vtranslate('Here is your self service portal login details:', $moduleName).'</td></tr><tr><td align="center"><br><table style="border:2px solid rgb(180,180,179);background-color:rgb(226,226,225);" cellspacing="0" cellpadding="10" border="0" width="75%"><tr>
+								<td><br>'.vtranslate('User ID').' : <font color="#990000"><strong><a target="_blank">'.$user_name.'</a></strong></font></td></tr><tr>
+								<td>'.vtranslate('Password').' : <font color="#990000"><strong>'.$password.'</strong></font></td></tr><tr>
+								<td align="center"><strong>'.$portalURL.'</strong></td>
+								</tr></table><br></td></tr><tr><td><strong>NOTE: </strong>'.vtranslate('We suggest you to change your password after logging in first time').'.<br>
+							</td></tr></table>';
+
+				$subject = 'Customer Portal Login Details';
+				$subject = decode_html(getMergedDescription($subject, $contactId, $moduleName));
+
+				$mailStatus = send_mail($moduleName, $user_name, $HELPDESK_SUPPORT_NAME, $HELPDESK_SUPPORT_EMAIL_ID, $subject, $contents, '', '', '', '', '', true);
+				$ret_msg = vtranslate('LBL_MAIL_COULDNOT_SENT', 'HelpDesk');
+				if ($mailStatus) {
+					$ret_msg = vtranslate('LBL_MAIL_SENT', 'HelpDesk');
+				}
+				$response->setResult($ret_msg);
+			} else if ($isActive && $support_end_date <= $current_date) {
+				throw new Exception('Access to the portal was disabled on '.$support_end_date, 1413);
+			} else if ($isActive == 0) {
+				throw new Exception('Portal access has not been enabled for this account.', 1414);
+			}
+		} else {
+			$response->setError('1412', 'Invalid email');
+		}
+		return $response;
+	}
+
+	function authenticatePortalUser($username, $password) {
+		// always return true
+		return true;
+	}
+
+	public function getCurrentPortalUser() {
+		$db = PearDatabase::getInstance();
+
+		$result = $db->pquery("SELECT prefvalue FROM vtiger_customerportal_prefs WHERE prefkey = 'userid' AND tabid = 0", array());
+		if ($db->num_rows($result)) {
+			return $db->query_result($result, 0, 'prefvalue');
+		}
+		return false;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Ping.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Ping.php
new file mode 100644
index 0000000000000000000000000000000000000000..2587079965c4cc670d266a4d73d63be25da724c3
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Ping.php
@@ -0,0 +1,19 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_Ping extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$response->setResult('login success');
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Request.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Request.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2ccbdbf075efa90124123d6bebf0a507054ee40
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Request.php
@@ -0,0 +1,55 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_API_Request {
+
+	private $valuemap;
+	private $rawvaluemap;
+	private $defaultmap = array();
+
+	function __construct($values = array(), $rawvalues = array()) {
+		$this->valuemap = $values;
+		$this->rawvaluemap = $rawvalues;
+	}
+
+	function get($key, $defvalue = '', $purify = true) {
+		if (isset($this->valuemap[$key])) {
+			return $purify ? /* vtlib_purify */($this->valuemap[$key]) : $this->valuemap[$key];
+		}
+		if ($defvalue === '' && isset($this->defaultmap[$key])) {
+			$defvalue = $this->defaultmap[$key];
+		}
+		return $defvalue;
+	}
+
+	function has($key) {
+		return isset($this->valuemap[$key]);
+	}
+
+	function getRaw($key, $defvalue = '') {
+		if (isset($this->rawvaluemap[$key])) {
+			return $this->rawvaluemap[$key];
+		}
+		return $this->get($key, $defvalue);
+	}
+
+	function set($key, $newvalue) {
+		$this->valuemap[$key] = $newvalue;
+	}
+
+	function setDefault($key, $defvalue) {
+		$this->defaultmap[$key] = $defvalue;
+	}
+
+	function getOperation() {
+		return $this->get('_operation');
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Response.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Response.php
new file mode 100644
index 0000000000000000000000000000000000000000..71c8ffe87c30efc698ac4fb5a957e08ef2a5e12f
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/Response.php
@@ -0,0 +1,63 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_API_Response {
+
+	private $error = NULL;
+	private $result = NULL;
+
+	function setError($code, $message) {
+		$error = array('code' => $code, 'message' => $message);
+		$this->error = $error;
+	}
+
+	function getError() {
+		return $this->error;
+	}
+
+	function hasError() {
+		return !is_null($this->error);
+	}
+
+	function setResult($result) {
+		$this->result = $result;
+	}
+
+	function getResult() {
+		return $this->result;
+	}
+
+	function addToResult($key, $value) {
+		$this->result[$key] = $value;
+	}
+
+	function prepareResponse() {
+		$response = array();
+		if ($this->result === NULL) {
+			$response['success'] = false;
+			$response['error'] = $this->error;
+		} else {
+			$response['success'] = true;
+			$response['result'] = $this->result;
+		}
+		return $response;
+	}
+
+	function emitJSON() {
+		return Zend_Json::encode($this->prepareResponse());
+	}
+
+	function emitHTML() {
+		if ($this->result === NULL)
+			return (is_string($this->error)) ? $this->error : var_export($this->error, true);
+		return $this->result;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SaveRecord.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SaveRecord.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e9bf19a36dfbb878c6872145a9fe17f77c38374
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SaveRecord.php
@@ -0,0 +1,216 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_SaveRecord extends CustomerPortal_FetchRecord {
+
+	protected $recordValues = false;
+	protected $mode = 'edit';
+
+	protected function isNewRecordRequest(CustomerPortal_API_Request $request) {
+		$recordid = $request->get('recordId');
+		return (preg_match("/([0-9]+)x0/", $recordid));
+	}
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		global $current_user;
+		$current_user = $this->getActiveUser();
+
+		if ($current_user) {
+			$module = $request->get('module');
+
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception("Module not accessible", 1412);
+				exit;
+			}
+
+
+
+			if (in_array($module, array('HelpDesk', 'Documents', 'Assets', 'Quotes', 'Contacts', 'Accounts'))) {
+				$recordId = $request->get('recordId');
+				if (!empty($recordId)) {
+					//Stop edit record if edit is disabled
+					if (!CustomerPortal_Utils::isModuleRecordEditable($module)) {
+						throw new Exception("Module record cannot be edited", 1412);
+						exit;
+					}
+				} else {
+					if (!CustomerPortal_Utils::isModuleRecordCreatable($module)) {
+						throw new Exception("Module record cannot be created", 1412);
+						exit;
+					}
+				}
+				$valuesJSONString = $request->get('values', '', false);
+				$values = "";
+
+				if (!empty($valuesJSONString) && is_string($valuesJSONString)) {
+					$values = Zend_Json::decode($valuesJSONString);
+				} else {
+					$values = $valuesJSONString; // Either empty or already decoded.
+				}
+				//Avoiding fetching fields from customerportal_fields for Accounts and Contacts
+				if ($module !== 'Contacts' && $module !== 'Accounts') {
+					//get active fieids with read , write permissions 
+					$activeFields = CustomerPortal_Utils::getActiveFields($module, true);
+					$editableFields = array();
+
+					foreach ($activeFields as $key => $value) {
+						if ($value == 1)
+							$editableFields[] = $key;
+					}
+					if ($module == 'HelpDesk') {
+						$editableFields[] = 'serviceid';
+						$editableFields[] = 'ticketstatus';
+						$editableFields[] = 'ticketpriorities';
+					}
+					if ($module == 'Quotes') {
+						$editableFields[] = 'quotestage';
+					}
+
+					if (!empty($values)) {
+						foreach ($values as $key => $value) {
+							if (!in_array($key, $editableFields)) {
+								throw new Exception("Specified fields not editable", 1412);
+								exit;
+							}
+						}
+					}
+				}
+
+				try {
+					if (vtws_recordExists($recordId)) {
+						// Retrieve or Initalize
+						if (!empty($recordId) && !$this->isNewRecordRequest($request)) {
+							$this->recordValues = vtws_retrieve($recordId, $current_user);
+						} else {
+							$this->recordValues = array();
+							// set assigned user to default assignee
+							$this->recordValues['assigned_user_id'] = CustomerPortal_Settings_Utils::getDefaultAssignee();
+						}
+
+						// Set the modified values
+						if (!empty($values)) {
+							foreach ($values as $name => $value) {
+								$this->recordValues[$name] = $value;
+							}
+						}
+						// set contact , Organization for Helpdesk record
+						if ($module == 'HelpDesk') {
+							$contactId = vtws_getWebserviceEntityId('Contacts', $this->getActiveCustomer()->id);
+							$this->recordValues['contact_id'] = $contactId;
+							$this->recordValues['from_portal'] = true;
+							$accountId = $this->getParent($contactId);
+							if (!empty($accountId))
+								$this->recordValues['parent_id'] = $accountId;
+						}
+
+						if ($module == 'Documents' && count($_FILES)) {
+							$file = $_FILES['file'];
+							$this->recordValues['notes_title'] = $request->get('filename');
+							$this->recordValues['filelocationtype'] = 'I'; // location type is internal
+							$this->recordValues['filestatus'] = '1'; //status always active
+							$this->recordValues['filename'] = $file['name'];
+							$this->recordValues['filetype'] = $file['type'];
+							$this->recordValues['filesize'] = $file['size'];
+						}
+
+						// Setting missing mandatory fields for record.
+						$describe = vtws_describe($module, $current_user);
+						$mandatoryFields = CustomerPortal_Utils:: getMandatoryFields($describe);
+						foreach ($mandatoryFields as $fieldName => $type) {
+							if (!isset($this->recordValues[$fieldName])) {
+								if ($type['name'] == 'reference') {
+									$crmId = Vtiger_Util_Helper::fillMandatoryFields($fieldName, $module);
+									$wsId = vtws_getWebserviceEntityId($type['refersTo'][0], $crmId);
+									$this->recordValues[$fieldName] = $wsId;
+								} else {
+									$this->recordValues[$fieldName] = Vtiger_Util_Helper::fillMandatoryFields($fieldName, $module);
+								}
+							}
+						}
+						// Update or Create
+						if (isset($this->recordValues['id'])) {
+							if ($module == 'Contacts' || $module == 'Accounts') {
+								$updatedStatus = vtws_update($this->recordValues, $current_user);
+								if ($updatedStatus['id'] == $recordId) {
+									$response = new CustomerPortal_API_Response();
+									$response->setResult($updatedStatus);
+								} else {
+									$response->setError("RECORD_NOT_FOUND", "Record does not exist");
+								}
+								return $response;
+							}
+							foreach ($mandatoryFields as $fieldName => $type) {
+								if (!isset($this->recordValues[$fieldName]) || empty($this->recordValues[$fieldName])) {
+									if ($type['name'] !== 'reference') {
+										$this->recordValues[$fieldName] = Vtiger_Util_Helper::fillMandatoryFields($fieldName, $module);
+									}
+								}
+							}
+							$this->recordValues = vtws_update($this->recordValues, $current_user);
+						} else {
+							$this->mode = 'create';
+							//Setting source to customer portal
+							$this->recordValues['source'] = 'CUSTOMER PORTAL';
+							$this->recordValues = vtws_create($module, $this->recordValues, $current_user);
+						}
+
+						// Update the record id
+						$request->set('recordId', $this->recordValues['id']);
+						$idComponents = explode('x', $this->recordValues['id']);
+						$recordId = $idComponents[1];
+
+						//Adding relation to Service Contracts
+
+						if ($module == 'HelpDesk' && !empty($values['serviceid'])) {
+							$contact = new Contacts();
+							$serviceId = $values['serviceid'];
+							$ids = explode('x', $serviceId);
+							$crmId = explode('x', $this->recordValues['id']);
+							$contact->save_related_module('HelpDesk', $crmId[1], 'ServiceContracts', array($ids[1]));
+						}
+
+						if ($module == 'Documents') {
+							$contact = new Contacts();
+							$contact->save_related_module('Contacts', $this->getActiveCustomer()->id, 'Documents', array($recordId));
+
+							//relate Document with a Ticket OR Project
+							$parentId = $request->get('parentId');
+
+							if (!empty($parentId) && $this->isRecordAccessible($parentId)) {
+								$focus = CRMEntity::getInstance('Documents');
+								$parentIdComponents = explode('x', $parentId);
+								$focus->insertintonotesrel($parentIdComponents[1], $recordId);
+							}
+						}
+
+						if (count($_FILES)) {
+							$_FILES = Vtiger_Util_Helper::transformUploadedFiles($_FILES, true);
+							$attachmentType = $request->get('attachmentType');
+							$focus = CRMEntity::getInstance($module);
+							$focus->uploadAndSaveFile($recordId, $module, $_FILES['file'], $attachmentType);
+						}
+
+						// Gather response with full details
+						$response = parent::process($request);
+					} else {
+						$response->setError("RECORD_NOT_FOUND", "Record does not exist");
+					}
+				} catch (Exception $e) {
+					$response->setError($e->getCode(), $e->getMessage());
+				}
+			} else {
+				$response->setError(1404, 'save operation not supported for this module');
+			}
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SearchFaqs.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SearchFaqs.php
new file mode 100644
index 0000000000000000000000000000000000000000..bea9cd3297bbb05ab0501b70d4084055e9e18fb5
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SearchFaqs.php
@@ -0,0 +1,50 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_SearchFaqs extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+		$module = "Faq";
+		global $adb;
+
+		if ($current_user) {
+			if (!CustomerPortal_Utils::isModuleActive($module)) {
+				throw new Exception($module." not accessible", 1412);
+				exit;
+			}
+
+			$searchKey = $request->get('searchKey');
+			$searchKey = decode_html(htmlspecialchars_decode($searchKey));
+			$searchKey = addslashes(addslashes($searchKey));
+			$searchFields = array('question', 'answer');
+
+			$sql = sprintf('SELECT id,question,answer,status FROM vtiger_faq WHERE status=? AND (');
+			$sql.= implode(" LIKE '%$searchKey%' OR ", $searchFields);
+			$sql.= " LIKE '%".$searchKey."%') ;";
+			$sqlResult = $adb->pquery($sql, array("Published"));
+			$num_rows = $adb->num_rows($sqlResult);
+			$data = array();
+			for ($i = 0; $i < $num_rows; $i++) {
+				$record = array();
+				$record['question'] = decode_html($adb->query_result($sqlResult, $i, 'question'));
+				$record['faq_answer'] = decode_html($adb->query_result($sqlResult, $i, 'answer'));
+				$record['faqstatus'] = decode_html($adb->query_result($sqlResult, $i, 'status'));
+				$record['id'] = vtws_getWebserviceEntityId("Faq", $adb->query_result($sqlResult, $i, 'id'));
+				$data[] = $record;
+			}
+
+			$response->setResult($data);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SearchRecords.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SearchRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..ccec270d926545c1eae45681c3dfb98850b45249
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/SearchRecords.php
@@ -0,0 +1,124 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_SearchRecords extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$current_user = $this->getActiveUser();
+		global $adb;
+
+		if ($current_user) {
+			$searchKey = $request->get('searchKey');
+			$orderBy = 'modifiedtime';
+
+			if (!empty($searchKey)) {
+				$portalActiveModules = CustomerPortal_Utils::getActiveModules();
+
+				if (!empty($portalActiveModules)) {
+					$searchResult = array();
+
+					foreach ($portalActiveModules as $key => $module) {
+						$moduleModel = Vtiger_Module_Model::getInstance($module);
+						//Restricting search to Contact related modules
+						if (in_array($module, array("Faq", "ProjectTask", "ProjectMilestone"))) {
+							// do nothing
+						} else {
+							$activeFields = CustomerPortal_Utils::getActiveFields($module);
+
+							// unset date, time fields as search will fail on them
+							foreach ($activeFields as $key => $field) {
+								$field_model = Vtiger_Field_Model::getInstance($field, $moduleModel);
+
+								if (in_array($field_model->getFieldDataType(), array('date', 'datetime', 'time', 'currency'))) {
+									unset($activeFields[$key]);
+								}
+							}
+
+							$describe = vtws_describe($module, $current_user);
+							$labelFields = $describe['labelFields'];
+							if ($module == 'Documents') {
+								$labelFields = 'notes_title';
+							}
+							if ($module == 'HelpDesk') {
+								$labelFields = 'ticket_title';
+							}
+
+							//generate query using Query Generator
+							$queryGenerator = new QueryGenerator($module, $current_user);
+							$labelFieldsArray = explode(',', $labelFields);
+							$queryGenerator->setFields($labelFieldsArray);
+
+							foreach ($activeFields as $fieldName) {
+								$queryGenerator->addCondition($fieldName, $searchKey, 'c', 'OR');
+							}
+							$query = $queryGenerator->getQuery();
+
+							$moduleLabel = CustomerPortal_Utils::getRelatedModuleLabel($module);
+							$relatedRecordWSIds = $this->relatedRecordIds($module, $moduleLabel);
+							$relatedRecordCRMIds = array();
+
+							//extract crm ids from webservice ids
+							if (!empty($relatedRecordWSIds)) {
+								foreach ($relatedRecordWSIds as $wsId) {
+									$idParts = explode('x', $wsId);
+									$relatedRecordCRMIds[] = $idParts[1];
+								}
+							}
+
+							$whereClause = "crmid IN ('".implode("','", $relatedRecordCRMIds)."')";
+							if (stripos($query, 'WHERE') == false) {
+								$query .= " WHERE ".$whereClause;
+							} else {
+								$queryParts = explode('WHERE', $query);
+								// adding crmid into query select fields list 
+								$subParts = explode('FROM', $queryParts[0]);
+								$queryParts[0] = $subParts[0].",vtiger_crmentity.crmid FROM ".$subParts[1];
+								$query = $queryParts[0]." WHERE ".$whereClause;
+								$query .= " AND (".$queryParts[1].")";
+							}
+							$query = sprintf('%s ORDER BY %s %s', $query, $orderBy, 'DESC');
+							$queryResult = $adb->pquery($query, array());
+							$result = array();
+
+							$num_rows = $adb->num_rows($queryResult);
+							if ($num_rows > 0) {
+								$result['uiLabel'] = decode_html(vtranslate($moduleLabel, $module));
+								$result['labelField'] = $labelFields;
+							}
+
+							// Parse result and construct response
+							while ($row = $adb->fetch_array($queryResult)) {
+								$record = array();
+								$crmId = $row['crmid'];
+								$recordWSId = vtws_getWebserviceEntityId($module, $crmId);
+								$record['id'] = $recordWSId;
+								$label = '';
+								foreach ($labelFieldsArray as $labelField) {
+									$fieldModel = Vtiger_Field_Model::getInstance($labelField, $moduleModel);
+									$label.= $row[$fieldModel->column]." ";
+								}
+								$record['label'] = decode_html($label);
+								$result[] = $record;
+							}
+
+							$searchResult[$module] = $result;
+						}
+					}
+				}
+			} else {
+				throw new Exception("Search key is empty", 1412);
+			}
+			$response->setResult($searchResult);
+			return $response;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/UpdateLoginDetails.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/UpdateLoginDetails.php
new file mode 100644
index 0000000000000000000000000000000000000000..b155321805813f6720fad1a964a7be71d502891e
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/UpdateLoginDetails.php
@@ -0,0 +1,32 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_UpdateLoginDetails extends CustomerPortal_API_Abstract {
+
+	function process(CustomerPortal_API_Request $request) {
+		$response = new CustomerPortal_API_Response();
+		$customer = $this->getActiveCustomer();
+		$status = $request->get('status');
+		global $adb;
+		$currentTime = $adb->formatDate(date('YmdHis'), true);
+
+		if ($status == 'Login') {
+			$sql = 'UPDATE vtiger_portalinfo SET login_time=? WHERE id=?';
+			$adb->pquery($sql, array($currentTime, $customer->id));
+		} elseif ($status == 'Logout') {
+			$sql = 'UPDATE vtiger_portalinfo SET logout_time=?, last_login_time=login_time WHERE id=?';
+			$adb->pquery($sql, array($currentTime, $customer->id));
+		}
+
+		$response->setResult(true);
+		return $response;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Request.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Request.php
new file mode 100644
index 0000000000000000000000000000000000000000..13fe50c271d9647f7beff6abeb40069e339b7300
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Request.php
@@ -0,0 +1,59 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_API_Request {
+
+	private $valuemap;
+	private $rawvaluemap;
+	private $defaultmap = array();
+
+	function __construct($values = array(), $rawvalues = array()) {
+		$this->valuemap = $values;
+		$this->rawvaluemap = $rawvalues;
+	}
+
+	function get($key, $defvalue = '', $purify = true) {
+		if (isset($this->valuemap[$key])) {
+			return $purify ? vtlib_purify($this->valuemap[$key]) : $this->valuemap[$key];
+		}
+		if ($defvalue === '' && isset($this->defaultmap[$key])) {
+			$defvalue = $this->defaultmap[$key];
+		}
+		return $defvalue;
+	}
+
+	function has($key) {
+		return isset($this->valuemap[$key]);
+	}
+
+	function getRaw($key, $defvalue = '') {
+		if (isset($this->rawvaluemap[$key])) {
+			return $this->rawvaluemap[$key];
+		}
+		return $this->get($key, $defvalue);
+	}
+
+	function set($key, $newvalue) {
+		$this->valuemap[$key] = $newvalue;
+	}
+
+	function setDefault($key, $defvalue) {
+		$this->defaultmap[$key] = $defvalue;
+	}
+
+	function getOperation() {
+		return $this->get('_operation');
+	}
+
+	function getLanguage() {
+		return $this->get('language');
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Response.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Response.php
new file mode 100644
index 0000000000000000000000000000000000000000..71c8ffe87c30efc698ac4fb5a957e08ef2a5e12f
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Response.php
@@ -0,0 +1,63 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_API_Response {
+
+	private $error = NULL;
+	private $result = NULL;
+
+	function setError($code, $message) {
+		$error = array('code' => $code, 'message' => $message);
+		$this->error = $error;
+	}
+
+	function getError() {
+		return $this->error;
+	}
+
+	function hasError() {
+		return !is_null($this->error);
+	}
+
+	function setResult($result) {
+		$this->result = $result;
+	}
+
+	function getResult() {
+		return $this->result;
+	}
+
+	function addToResult($key, $value) {
+		$this->result[$key] = $value;
+	}
+
+	function prepareResponse() {
+		$response = array();
+		if ($this->result === NULL) {
+			$response['success'] = false;
+			$response['error'] = $this->error;
+		} else {
+			$response['success'] = true;
+			$response['result'] = $this->result;
+		}
+		return $response;
+	}
+
+	function emitJSON() {
+		return Zend_Json::encode($this->prepareResponse());
+	}
+
+	function emitHTML() {
+		if ($this->result === NULL)
+			return (is_string($this->error)) ? $this->error : var_export($this->error, true);
+		return $this->result;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/SettingsUtils.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/SettingsUtils.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c3e37b66bae817053ea746a182162762039887c
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/SettingsUtils.php
@@ -0,0 +1,39 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_Settings_Utils {
+
+	static function getDefaultMode($module) {
+		global $adb;
+		$sql = "SELECT vtiger_customerportal_fields.records_visible FROM vtiger_customerportal_fields
+				INNER JOIN vtiger_tab ON vtiger_customerportal_fields.tabid= vtiger_tab.tabid WHERE vtiger_tab.name= ?";
+		$result = $adb->pquery($sql, array($module));
+		$IsVisible = $adb->query_result($result, 0, 'records_visible');
+
+		if ($IsVisible) {
+			return 'all';
+		} else {
+			return 'mine';
+		}
+	}
+
+	static function getDefaultAssignee() {
+		global $adb;
+		$sql = "SELECT default_assignee FROM vtiger_customerportal_settings LIMIT 1";
+		$result = $adb->pquery($sql);
+		$default_assignee = $adb->query_result($result, 0, 'default_assignee');
+
+		if (!empty($default_assignee)) {
+			$userId = vtws_getWebserviceEntityId('Users', $default_assignee);
+			return $userId;
+		}
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Utils.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Utils.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a9d9631dbadacaff630641cc4224a02305658d9
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/helpers/Utils.php
@@ -0,0 +1,285 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+class CustomerPortal_Utils {
+
+	static function getImageDetails($recordId, $module) {
+		global $adb;
+		$sql = "SELECT vtiger_attachments.*, vtiger_crmentity.setype FROM vtiger_attachments
+					INNER JOIN vtiger_seattachmentsrel ON vtiger_seattachmentsrel.attachmentsid = vtiger_attachments.attachmentsid
+					INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = vtiger_attachments.attachmentsid
+						WHERE vtiger_crmentity.setype = ? and vtiger_seattachmentsrel.crmid = ?";
+
+		$result = $adb->pquery($sql, array($module.' Image', $recordId));
+
+		$imageId = $adb->query_result($result, 0, 'attachmentsid');
+		$imagePath = $adb->query_result($result, 0, 'path');
+		$imageName = $adb->query_result($result, 0, 'name');
+		$imageType = $adb->query_result($result, 0, 'type');
+		$imageOriginalName = urlencode(decode_html($imageName));
+
+		if (!empty($imageName)) {
+			$imageDetails[] = array(
+				'id' => $imageId,
+				'orgname' => $imageOriginalName,
+				'path' => $imagePath.$imageId,
+				'name' => $imageName,
+				'type' => $imageType
+			);
+		}
+
+		if (!isset($imageDetails))
+			return;
+		else
+			return self::getEncodedImage($imageDetails[0]);
+	}
+
+	static function getEncodedImage($imageDetails) {
+		global $root_directory;
+		$image = $root_directory.'/'.$imageDetails['path'].'_'.$imageDetails['name'];
+		$image_data = file_get_contents($image);
+		$encoded_image = base64_encode($image_data);
+		$encodedImageData = array();
+		$encodedImageData['imagetype'] = $imageDetails['type'];
+		$encodedImageData['imagedata'] = $encoded_image;
+		return $encodedImageData;
+	}
+
+	public static function getActiveModules() {
+		$activeModules = Vtiger_Cache::get('CustomerPortal', 'activeModules'); // need to flush cache when modules updated at CRM settings
+
+		if (empty($activeModules)) {
+			global $adb;
+			$sql = "SELECT vtiger_tab.name FROM vtiger_customerportal_tabs INNER JOIN vtiger_tab 
+						ON vtiger_customerportal_tabs.tabid= vtiger_tab.tabid AND vtiger_tab.presence= ? WHERE vtiger_customerportal_tabs.visible = ? ";
+			$sqlResult = $adb->pquery($sql, array(0, 1));
+
+			for ($i = 0; $i < $adb->num_rows($sqlResult); $i++) {
+				$activeModules[] = $adb->query_result($sqlResult, $i, 'name');
+			}
+			//Checking if module is active at Module Manager 
+			foreach ($activeModules as $index => $moduleName) {
+				$moduleModel = Vtiger_Module_Model::getInstance($moduleName);
+				if (!$moduleModel || !$moduleModel->isActive() || Vtiger_Runtime::isRestricted('modules', $moduleName)) {
+					unset($activeModules[$index]);
+				}
+			}
+			Vtiger_Cache::set('CustomerPortal', 'activeModules', $activeModules);
+		}
+		return $activeModules;
+	}
+
+	public static function isModuleActive($module) {
+		$activeModules = self::getActiveModules();
+		$defaultAllowedModules = array("ModComments", "History", "Contacts", "Accounts");
+
+		if (in_array($module, $defaultAllowedModules)) {
+			return true;
+		} else if (in_array($module, $activeModules) && !Vtiger_Runtime::isRestricted('modules', $module)) {
+			return true;
+		}
+		return false;
+	}
+
+	static function resolveRecordValues(&$record, $user = null, $ignoreUnsetFields = false) {
+		$userTypeFields = array('assigned_user_id', 'creator', 'userid', 'created_user_id', 'modifiedby', 'folderid');
+
+		if (empty($record))
+			return $record;
+
+		$module = Vtiger_Util_Helper::detectModulenameFromRecordId($record['id']);
+		$fieldnamesToResolve = Vtiger_Util_Helper::detectFieldnamesToResolve($module);
+		$activeFields = self::getActiveFields($module);
+
+		if (is_array($activeFields) && $module !== 'ModComments') {
+			foreach ($fieldnamesToResolve as $key => $field) {
+				if (!in_array($field, $activeFields)) {
+					unset($fieldnamesToResolve[$key]);
+				}
+			}
+		}
+
+		if (!empty($fieldnamesToResolve)) {
+			foreach ($fieldnamesToResolve as $resolveFieldname) {
+
+				if (isset($record[$resolveFieldname]) && !empty($record[$resolveFieldname])) {
+					$fieldvalueid = $record[$resolveFieldname];
+
+					if (in_array($resolveFieldname, $userTypeFields)) {
+						$fieldvalue = decode_html(trim(vtws_getName($fieldvalueid, $user)));
+					} else {
+						$fieldvalue = Vtiger_Util_Helper::fetchRecordLabelForId($fieldvalueid);
+					}
+					$record[$resolveFieldname] = array('value' => $fieldvalueid, 'label' => $fieldvalue);
+				}
+			}
+		}
+		return $record;
+	}
+
+	static function getRelatedModuleLabel($relatedModule, $parentModule = "Contacts") {
+		$relatedModuleLabel = Vtiger_Cache::get('CustomerPortal', $relatedModule.':label');
+
+		if (empty($relatedModuleLabel)) {
+			global $adb;
+
+			if (in_array($relatedModule, array('ProjectTask', 'ProjectMilestone')))
+				$parentModule = 'Project';
+
+			$sql = "SELECT vtiger_relatedlists.label FROM vtiger_relatedlists
+						INNER JOIN vtiger_customerportal_tabs ON vtiger_relatedlists.related_tabid =vtiger_customerportal_tabs.tabid
+						INNER JOIN vtiger_tab ON vtiger_customerportal_tabs.tabid =vtiger_tab.tabid WHERE vtiger_tab.name=? AND vtiger_relatedlists.tabid=?";
+			$sqlResult = $adb->pquery($sql, array($relatedModule, getTabid($parentModule)));
+
+			if ($adb->num_rows($sqlResult) > 0) {
+				$relatedModuleLabel = $adb->query_result($sqlResult, 0, 'label');
+				Vtiger_Cache::set('CustomerPortal', $relatedModule.':label', $relatedModuleLabel);
+			}
+		}
+		return $relatedModuleLabel;
+	}
+
+	static function getActiveFields($module, $withPermissions = false) {
+		$activeFields = Vtiger_Cache::get('CustomerPortal', 'activeFields'); // need to flush cache when fields updated at CRM settings
+
+		if (empty($activeFields)) {
+			global $adb;
+			$sql = "SELECT name, fieldinfo FROM vtiger_customerportal_fields INNER JOIN vtiger_tab ON vtiger_customerportal_fields.tabid=vtiger_tab.tabid";
+			$sqlResult = $adb->pquery($sql, array());
+			$num_rows = $adb->num_rows($sqlResult);
+
+			for ($i = 0; $i < $num_rows; $i++) {
+				$retrievedModule = $adb->query_result($sqlResult, $i, 'name');
+				$fieldInfo = $adb->query_result($sqlResult, $i, 'fieldinfo');
+				$activeFields[$retrievedModule] = $fieldInfo;
+			}
+			Vtiger_Cache::set('CustomerPortal', 'activeFields', $activeFields);
+		}
+
+		$fieldsJSON = $activeFields[$module];
+		$data = Zend_Json::decode(decode_html($fieldsJSON));
+		$fields = array();
+
+		if (!empty($data)) {
+			foreach ($data as $key => $value) {
+				if (self::isViewable($key, $module)) {
+					if ($withPermissions) {
+						$fields[$key] = $value;
+					} else {
+						$fields[] = $key;
+					}
+				}
+			}
+		}
+		return $fields;
+	}
+
+	static function str_replace_last($search, $replace, $str) {
+		if (( $pos = strrpos($str, $search) ) !== false) {
+			$search_length = strlen($search);
+			$str = substr_replace($str, $replace, $pos, $search_length);
+		}
+		return $str;
+	}
+
+	static function isViewable($fieldName, $module) {
+		global $db;
+		$db = PearDatabase::getInstance();
+		$tabidSql = "SELECT tabid from vtiger_tab WHERE name = ?";
+		$tabidResult = $db->pquery($tabidSql, array($module));
+		if ($db->num_rows($tabidResult)) {
+			$tabId = $db->query_result($tabidResult, 0, 'tabid');
+		}
+		$presenceSql = "SELECT presence,displaytype FROM vtiger_field WHERE fieldname=? AND tabid = ?";
+		$presenceResult = $db->pquery($presenceSql, array($fieldName, $tabId));
+		$num_rows = $db->num_rows($presenceResult);
+		if ($num_rows) {
+			$fieldPresence = $db->query_result($presenceResult, 0, 'presence');
+			$displayType = $db->query_result($presenceResult, 0, 'displaytype');
+			if ($fieldPresence == 0 || $fieldPresence == 2 && $displayType !== 4) {
+				return true;
+			} else {
+				return false;
+			}
+		}
+	}
+
+	static function isReferenceType($fieldName, $describe) {
+		$type = self::getFieldType($fieldName, $describe);
+
+		if ($type === 'reference') {
+			return true;
+		}
+		return false;
+	}
+
+	static function isOwnerType($fieldName, $describe) {
+		$type = self::getFieldType($fieldName, $describe);
+
+		if ($type === 'owner') {
+			return true;
+		}
+		return false;
+	}
+
+	static function getFieldType($fieldName, $describe) {
+		$fields = $describe['fields'];
+
+		foreach ($fields as $field) {
+			if ($fieldName === $field['name']) {
+				return $field['type']['name'];
+			}
+		}
+		return null;
+	}
+
+	static function getMandatoryFields($describe) {
+
+		$fields = $describe["fields"];
+		$mandatoryFields = array();
+		foreach ($fields as $field) {
+			if ($field['mandatory'] == 1) {
+				$mandatoryFields[$field['name']] = $field['type'];
+			}
+		}
+		return $mandatoryFields;
+	}
+
+	static function isModuleRecordCreatable($module) {
+		global $db;
+		$db = PearDatabase::getInstance();
+		$recordPermissionQuery = "SELECT createrecord from vtiger_customerportal_tabs WHERE tabid=?";
+		$createPermissionResult = $db->pquery($recordPermissionQuery, array(getTabid($module)));
+		$createPermission = $db->query_result($createPermissionResult, 0, 'createrecord');
+		return $createPermission;
+	}
+
+	static function isModuleRecordEditable($module) {
+		global $db;
+		$db = PearDatabase::getInstance();
+		$recordPermissionQuery = "SELECT editrecord from vtiger_customerportal_tabs WHERE tabid=?";
+		$editPermissionResult = $db->pquery($recordPermissionQuery, array(getTabid($module)));
+		$editPermission = $db->query_result($editPermissionResult, 0, 'editrecord');
+		return $editPermission;
+	}
+
+	//Function to get all Ids when mode is set to published.
+
+	static function getAllRecordIds($module, $current_user) {
+		$relatedIds = array();
+		$sql = sprintf('SELECT id FROM %s;', $module);
+		$result = vtws_query($sql, $current_user);
+		foreach ($result as $resultArray) {
+			$relatedIds[] = $resultArray['id'];
+		}
+		return $relatedIds;
+	}
+
+}
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/include.inc b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/include.inc
new file mode 100644
index 0000000000000000000000000000000000000000..9c57495b3be7c0aef42df90fe20efe81619254cb
--- /dev/null
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/include.inc
@@ -0,0 +1,51 @@
+<?php
+/* +**********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.1
+ * ("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.
+ * ***********************************************************************************/
+
+chdir(dirname(__FILE__).'/../../');
+
+include_once 'includes/Loader.php';
+include_once 'includes/runtime/Globals.php';
+include_once 'include/Webservices/Relation.php';
+require_once 'include/utils/utils.php';
+include_once 'include/Webservices/Query.php';
+include_once 'include/Webservices/QueryRelated.php';
+include_once 'include/Webservices/RetrieveRelated.php';
+include_once 'include/Webservices/VtigerModuleOperation.php';
+include_once 'include/Webservices/Create.php';
+include_once 'include/Webservices/Retrieve.php';
+include_once 'include/Webservices/History.php';
+include_once 'include/Webservices/Utils.php';
+include_once 'include/Zend/Json.php';
+include_once 'include/QueryGenerator/QueryGenerator.php';
+include_once 'include/Webservices/DescribeObject.php';
+include_once 'includes/runtime/LanguageHandler.php';
+include_once 'modules/Emails/class.phpmailer.php';
+include_once 'modules/ModTracker/ModTracker.php';
+include_once 'modules/Contacts/Contacts.php';
+include_once 'modules/Vtiger/helpers/Util.php';
+include_once 'includes/runtime/BaseModel.php';
+include_once 'modules/Vtiger/uitypes/Base.php';
+include_once 'modules/Vtiger/models/CompanyDetails.php';
+include_once 'modules/Vtiger/models/Field.php';
+include_once 'modules/Vtiger/uitypes/Time.php';
+include_once 'modules/Emails/mail.php';
+require_once 'vtlib/Vtiger/Runtime.php';
+include_once 'includes/runtime/Viewer.php';
+include_once 'includes/runtime/Theme.php';
+include_once 'includes/http/Request.php';
+include_once 'libraries/Smarty/libs/sysplugins/smarty_security.php';
+include_once dirname(__FILE__).'/helpers/Request.php';
+include_once dirname(__FILE__).'/helpers/Response.php';
+include_once dirname(__FILE__).'/helpers/Utils.php';
+include_once dirname(__FILE__).'/helpers/SettingsUtils.php';
+include_once dirname(__FILE__).'/apis/AbstractApi.php';
+include_once dirname(__FILE__).'/apis/FetchRecord.php';
+include_once dirname(__FILE__).'/Config.php';
+
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/schema.xml b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/schema.xml
index c33b366ffc11369189f48666fd57826986f0acb5..9fb4a1f7da0dd95def957bb7b937325b05b5a2ba 100644
--- a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/schema.xml
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/schema.xml
@@ -4,27 +4,27 @@
 		<table>
 			<name>vtiger_customerportal_tabs</name>
 			<sql><![CDATA[CREATE TABLE `vtiger_customerportal_tabs` (
-  `tabid` int(19) NOT NULL,
-  `visible` int(1) default '1',
-  `sequence` int(1) default NULL,
-  PRIMARY KEY  (`tabid`)
-)]]></sql>
+						`tabid` int(19) NOT NULL,
+						`visible` int(1) default '1',
+						`sequence` int(1) default NULL,
+						PRIMARY KEY  (`tabid`)
+			)]]></sql>
 		</table>
 		<table>
 			<name>vtiger_customerportal_fields</name>
 			<sql><![CDATA[CREATE TABLE `vtiger_customerportal_fields` (
-  `tabid` int(19) NOT NULL,
-  `fieldid` int(19) default NULL,
-  `visible` int(1) default NULL
-)]]></sql>
+							`tabid` int(19) NOT NULL,
+							`fieldid` int(19) default NULL,
+							`visible` int(1) default NULL
+			)]]></sql>
 		</table>
 		<table>
 			<name>vtiger_customerportal_prefs</name>
 			<sql><![CDATA[CREATE TABLE `vtiger_customerportal_prefs` (
-  `tabid` int(11) NOT NULL,
-  `prefkey` varchar(100) default NULL,
-  `prefvalue` int(20) default NULL
-)]]></sql>
+							`tabid` int(11) NOT NULL,
+							`prefkey` varchar(100) default NULL,
+							`prefvalue` int(20) default NULL
+			)]]></sql>
 		</table>
 	</tables>
 </schema>
diff --git a/pkg/vtiger/modules/CustomerPortal/settings/actions/Save.php b/pkg/vtiger/modules/CustomerPortal/settings/actions/Save.php
index 1b95d458d0318e8d973c29ebba1066ec8cc8521f..0bd65003eea490027c57eb1505f05f4ef182554e 100644
--- a/pkg/vtiger/modules/CustomerPortal/settings/actions/Save.php
+++ b/pkg/vtiger/modules/CustomerPortal/settings/actions/Save.php
@@ -25,7 +25,6 @@ class Settings_CustomerPortal_Save_Action extends Settings_Vtiger_Index_Action {
 			$moduleModel->set('shortcuts', $request->get('defaultShortcuts'));
 			$moduleModel->set('moduleFieldsInfo', $request->get('moduleFieldsInfo'));
 			$moduleModel->set('relatedModuleList', $request->get('relatedModuleList'));
-			$moduleModel->set('charts', $request->get('activeCharts'));
 			$moduleModel->set('widgets', $request->get('activeWidgets'));
 			$moduleModel->set('recordsVisible', $request->get('recordsVisible'));
 			$moduleModel->set('recordPermissions', $request->get('recordPermissions'));
diff --git a/pkg/vtiger/modules/CustomerPortal/settings/models/Module.php b/pkg/vtiger/modules/CustomerPortal/settings/models/Module.php
index 6cadc8f1127ccb7722d6184f532ddc67999dba11..bf5937465d5cefcb7af7468402b499111cf20c2d 100644
--- a/pkg/vtiger/modules/CustomerPortal/settings/models/Module.php
+++ b/pkg/vtiger/modules/CustomerPortal/settings/models/Module.php
@@ -125,12 +125,9 @@ class Settings_CustomerPortal_Module_Model extends Settings_Vtiger_Module_Model
 
 		//Update the dashboard widgets, charts, announcement and support_notification details.
 		$activeWidgets['widgets'] = $widgets;
-		$activeCharts['charts'] = $charts;
 		$dashboardWidgets = json_encode($activeWidgets);
-		$dashboardCharts = json_encode($activeCharts);
-		if ($dashboardWidgets || $dashboardCharts) {
-			$db->pquery('UPDATE vtiger_customerportal_settings SET default_assignee = ? ,support_notification = ?
-						,announcement = ?,widgets = ?,charts=?', array($defaultAssignee, $renewalPeriod, $announcement, $dashboardWidgets, $dashboardCharts));
+		if ($dashboardWidgets) {
+			$db->pquery('UPDATE vtiger_customerportal_settings SET default_assignee=?, support_notification=?, announcement=?, widgets=?', array($defaultAssignee, $renewalPeriod, $announcement, $dashboardWidgets));
 		}
 		//Update module field info
 		if (!empty($moduleFieldsInfo)) {
@@ -214,12 +211,9 @@ class Settings_CustomerPortal_Module_Model extends Settings_Vtiger_Module_Model
 				$dashboardInfo['announcement'] = $row['announcement'];
 				$dashboardInfo['shortcuts'] = decode_html($row['shortcuts']);
 				$dashboardInfo['widgets'] = decode_html($row['widgets']);
-				$dashboardInfo['charts'] = decode_html($row['charts']);
 			}
 			$currentWidgets = json_decode($dashboardInfo['widgets'], true);
-			$currentCharts = json_decode($dashboardInfo['charts'], true);
 			$dashboardInfo['widgets'] = json_encode($currentWidgets);
-			$dashboardInfo['charts'] = json_encode($currentCharts);
 			$this->set('dashboardInfo', $dashboardInfo);
 		}
 		return $this;
diff --git a/pkg/vtiger/modules/CustomerPortal/settings/views/Index.php b/pkg/vtiger/modules/CustomerPortal/settings/views/Index.php
index 9a1ef79987ef4470d85c8cca6ac67f02ac8aa78c..b7ebe1f7423f508ea80678359254a121898dc836 100644
--- a/pkg/vtiger/modules/CustomerPortal/settings/views/Index.php
+++ b/pkg/vtiger/modules/CustomerPortal/settings/views/Index.php
@@ -45,12 +45,10 @@ class Settings_CustomerPortal_Index_View extends Settings_Vtiger_Index_View {
 		$default_shortcuts = $dashboardInfo['shortcuts'];
 		$announcement = $dashboardInfo['announcement'];
 		$widgets = json_decode($dashboardInfo['widgets'], true);
-		$charts = json_decode($dashboardInfo['charts'], true);
 		$supportNotification = $dashboardInfo['support_notification'];
 		$viewer->assign('DEFAULT_SHORTCUTS', $default_shortcuts);
 		$viewer->assign('ANNOUNCEMENT', $announcement);
 		$viewer->assign('WIDGETS', $widgets);
-		$viewer->assign('CHARTS', $charts);
 		$viewer->assign('SUPPORTNOTIFICATION', $supportNotification);
 		$viewer->assign('WIDGETS_MODULE_LIST', $widgetsModuleList);