- Added comprehensive AI Assistant system (aiassist/ directory): * Vector search and embedding capabilities * Typebot proxy integration * Elastic search functionality * Message classification and chat history * MCP proxy for external integrations - Implemented Court Status API (GetCourtStatus.php): * Real-time court document status checking * Integration with external court systems * Comprehensive error handling and logging - Enhanced S3 integration: * Improved file backup system with metadata * Batch processing capabilities * Enhanced error logging and recovery * Copy operations with URL fixing - Added Telegram contact creation API - Improved error logging across all modules - Enhanced callback system for AI responses - Extensive backup file storage with timestamps - Updated documentation and README files - File storage improvements: * Thousands of backup files with proper metadata * Fix operations for broken file references * Project-specific backup and recovery systems * Comprehensive file integrity checking Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
321 lines
16 KiB
PHP
321 lines
16 KiB
PHP
<?php
|
|
/* ********************************************************************************
|
|
* The content of this file is subject to the Mobile App 4 You license.
|
|
* ("License"); You may not use this file except in compliance with the License
|
|
* The Initial Developer of the Original Code is IT-Solutions4You s.r.o.
|
|
* Portions created by IT-Solutions4You s.r.o. are Copyright(C) IT-Solutions4You s.r.o.
|
|
* All Rights Reserved.
|
|
* ****************************************************************************** */
|
|
|
|
class ITS4YouMobileApp_DetailRecord_Model extends Vtiger_Base_Model
|
|
{
|
|
/**
|
|
* Function to get the id of the record
|
|
* @return <Number> - Record Id
|
|
*/
|
|
public function getId()
|
|
{
|
|
return $this->get('id');
|
|
}
|
|
|
|
/**
|
|
* Function to get the Module to which the record belongs
|
|
* @return Vtiger_Module_Model
|
|
*/
|
|
public function getModule()
|
|
{
|
|
return $this->module;
|
|
}
|
|
|
|
/**
|
|
* Function to set the Module to which the record belongs from the Module model instance
|
|
* @param <Vtiger_Module_Model> $module
|
|
* @return Vtiger_Record_Model or Module Specific Record Model instance
|
|
*/
|
|
public function setModuleFromInstance($module)
|
|
{
|
|
$this->module = $module;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Function to get the name of the module to which the record belongs
|
|
* @return <String> - Record Module Name
|
|
*/
|
|
public function getModuleName()
|
|
{
|
|
return $this->getModule()->get('name');
|
|
}
|
|
|
|
/**
|
|
* Function to set the entity instance of the record
|
|
* @param CRMEntity $entity
|
|
* @return Vtiger_Record_Model instance
|
|
*/
|
|
public function setEntity($entity)
|
|
{
|
|
$this->entity = $entity;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Static Function to get the instance of the Vtiger Record Model given the recordid and the module name
|
|
* @param <Number> $recordId
|
|
* @param <String> $moduleName
|
|
* @return ITS4YouMobileApp_DetailRecord_Model or Module Specific Record Model instance
|
|
*/
|
|
public static function getInstanceById($recordId, $module = null)
|
|
{
|
|
//TODO: Handle permissions
|
|
if (is_object($module) && is_a($module, 'Vtiger_Module_Model')) {
|
|
$moduleName = $module->get('name');
|
|
} elseif (is_string($module)) {
|
|
$module = Vtiger_Module_Model::getInstance($module);
|
|
$moduleName = $module->get('name');
|
|
} elseif (empty($module)) {
|
|
$moduleName = getSalesEntityType($recordId);
|
|
$module = Vtiger_Module_Model::getInstance($moduleName);
|
|
}
|
|
|
|
$focus = CRMEntity::getInstance($moduleName);
|
|
$focus->id = $recordId;
|
|
$focus->retrieve_entity_info($recordId, $moduleName);
|
|
$instance = new ITS4YouMobileApp_DetailRecord_Model();
|
|
return $instance->setData($focus->column_fields)->set('id', $recordId)->setModuleFromInstance($module)->setEntity($focus);
|
|
}
|
|
|
|
public static function getComments($recordId, $module = null, $startIndex = 0, $pageLimit = 10)
|
|
{
|
|
$self = self::getInstanceById($recordId, $module);
|
|
return $self->getRollupComments($startIndex, $pageLimit);
|
|
}
|
|
|
|
public function getRollupComments($startIndex = 0, $pageLimit = 10)
|
|
{
|
|
$rollupComments = array();
|
|
$modulename = $this->getModuleName();
|
|
$recordId = $this->getId();
|
|
|
|
$relatedModuleRecordIds = $this->getCommentEnabledRelatedEntityIds($modulename, $recordId);
|
|
array_unshift($relatedModuleRecordIds, $recordId);
|
|
|
|
if ($relatedModuleRecordIds) {
|
|
|
|
$listView = ITS4YouMobileApp_ListView_Model::getInstance('ModComments');
|
|
$queryGenerator = $listView->get('query_generator');
|
|
$queryGenerator->setFields(array('parent_comments', 'createdtime', 'modifiedtime', 'related_to', 'assigned_user_id',
|
|
'commentcontent', 'creator', 'id', 'customer', 'reasontoedit', 'userid', 'from_mailconverter', 'is_private', 'customer_email'));
|
|
|
|
$query = $queryGenerator->getQuery();
|
|
|
|
$query .= " AND vtiger_modcomments.related_to IN (" . generateQuestionMarks($relatedModuleRecordIds)
|
|
. ") AND vtiger_modcomments.parent_comments=0 ORDER BY vtiger_crmentity.createdtime DESC LIMIT "
|
|
. " $startIndex,$pageLimit";
|
|
|
|
$db = PearDatabase::getInstance();
|
|
$result = $db->pquery($query, $relatedModuleRecordIds);
|
|
if ($db->num_fields($result)) {
|
|
for ($i = 0; $i < $db->num_rows($result); $i++) {
|
|
$rowdata = $db->query_result_rowdata($result, $i);
|
|
$recordInstance = new ModComments_Record_Model();
|
|
$rowdata['module'] = getSalesEntityType($rowdata['related_to']);
|
|
$recordInstance->setData($rowdata);
|
|
$rollupComments[] = $recordInstance;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $rollupComments;
|
|
}
|
|
|
|
function getCommentEnabledRelatedEntityIds($modulename, $recordId)
|
|
{
|
|
$user = Users_Record_Model::getCurrentUserModel();
|
|
$relatedModuleRecordIds = array();
|
|
//User fields are restricted types
|
|
$restrictedFieldUITypes = array(52, 53);
|
|
$moduleInstance = Vtiger_Module_Model::getInstance($modulename);
|
|
$referenceFieldsModels = $moduleInstance->getFieldsByType('reference');
|
|
$userPrevilegesModel = Users_Privileges_Model::getInstanceById($user->id);
|
|
$directrelatedModuleRecordIds = array();
|
|
|
|
foreach ($referenceFieldsModels as $referenceFieldsModel) {
|
|
$relmoduleFieldUIType = $referenceFieldsModel->get('uitype');
|
|
$relmoduleFieldname = $referenceFieldsModel->get('name');
|
|
$relModuleFieldValue = $this->get($relmoduleFieldname);
|
|
|
|
if (!empty($relModuleFieldValue) && !in_array($relmoduleFieldUIType, $restrictedFieldUITypes) && isRecordExists($relModuleFieldValue)) {
|
|
$relModuleRecordModel = Vtiger_Record_Model::getInstanceById($relModuleFieldValue);
|
|
$relmodule = $relModuleRecordModel->getModuleName();
|
|
|
|
$relatedmoduleModel = Vtiger_Module_Model::getInstance($relmodule);
|
|
$isCommentEnabled = $relatedmoduleModel->isCommentEnabled();
|
|
|
|
if ($isCommentEnabled) {
|
|
$tabid = getTabid($relmodule);
|
|
$modulePermission = $userPrevilegesModel->hasModulePermission($tabid);
|
|
$hasDetailViewPermission = Users_Privileges_Model::isPermitted($relmodule, 'DetailView', $relModuleFieldValue);
|
|
|
|
if ($modulePermission && $hasDetailViewPermission)
|
|
$directrelatedModuleRecordIds[] = $relModuleFieldValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
$moduleModel = Vtiger_Module_Model::getInstance($modulename);
|
|
$relatedModuleModels = Vtiger_Relation_Model::getAllRelations($moduleModel, false);
|
|
$commentEnabledModules = array();
|
|
|
|
foreach ($relatedModuleModels as $relatedModuleModel) {
|
|
$relatedModuleName = $relatedModuleModel->get('relatedModuleName');
|
|
$relatedmoduleModel = Vtiger_Module_Model::getInstance($relatedModuleName);
|
|
$isCommentEnabled = $relatedmoduleModel->isCommentEnabled();
|
|
|
|
if ($isCommentEnabled) {
|
|
$tabid = getTabid($relatedModuleName);
|
|
$modulePermission = $userPrevilegesModel->hasModulePermission($tabid);
|
|
|
|
if ($modulePermission)
|
|
$commentEnabledModules['related_modules'][] = $relatedModuleModel->get('relation_id');
|
|
}
|
|
}
|
|
|
|
$indirectrelatedModuleRecordIds = $this->getRelatedModuleRecordIds($commentEnabledModules['related_modules'], array($recordId), true);
|
|
|
|
return array_merge($relatedModuleRecordIds, $directrelatedModuleRecordIds, $indirectrelatedModuleRecordIds);
|
|
}
|
|
|
|
public function getRelatedModuleRecordIds($relationIds, $recordIds = array(), $nonAdminCheck = false)
|
|
{
|
|
$db = PearDatabase::getInstance();
|
|
if (empty($relationIds)) return array();
|
|
|
|
$focus = CRMEntity::getInstance($this->getModuleName());
|
|
$relatedModuleMapping = $focus->related_module_table_index;
|
|
|
|
$relationFieldMapping = array();
|
|
$queryParams = array($this->getId());
|
|
foreach ($relationIds as $reltionId) {
|
|
array_push($queryParams, $reltionId);
|
|
}
|
|
$query = "SELECT relationfieldid,related_tabid
|
|
FROM vtiger_relatedlists
|
|
WHERE vtiger_relatedlists.tabid=? AND relation_id IN (" . generateQuestionMarks($relationIds) . ")";
|
|
|
|
|
|
$relationRes = $db->pquery($query, $queryParams);
|
|
|
|
$num_rows = $db->num_rows($relationRes);
|
|
for ($i = 0; $i < $num_rows; $i++) {
|
|
$relatedTabId = $db->query_result($relationRes, $i, 'related_tabid');
|
|
$relationfieldid = $db->query_result($relationRes, $i, 'relationfieldid');
|
|
$relatedModuleModel = Vtiger_Module_Model::getInstance($relatedTabId);
|
|
$relationFieldMapping[] = array('relatedModuleName' => $relatedModuleModel->getName(), 'relationfieldid' => $relationfieldid);
|
|
}
|
|
|
|
$relatedIds = array();
|
|
if (!empty($relationFieldMapping)) {
|
|
foreach ($relationFieldMapping as $mappingDetails) {
|
|
//for ($i=0; $i<count($relatedModules); $i++) {
|
|
$params = array();
|
|
$module = $mappingDetails['relatedModuleName'];
|
|
$relationFieldId = $mappingDetails['relationfieldid'];
|
|
$sql = "SELECT vtiger_crmentity.crmid FROM vtiger_crmentity";
|
|
|
|
|
|
if (empty($relationFieldId)) {
|
|
$tablename = $relatedModuleMapping[$module]['table_name'];
|
|
$tabIndex = $relatedModuleMapping[$module]['table_index'];
|
|
$relIndex = $relatedModuleMapping[$module]['rel_index'];
|
|
//To show related records comments in documents, should get related document records from vtiger_senotesrel.
|
|
if (empty($tablename) && $this->getModuleName() == 'Documents') {
|
|
$tablename = 'vtiger_senotesrel';
|
|
$tabIndex = 'crmid';
|
|
$relIndex = 'notesid';
|
|
//To show related Document comments in current module
|
|
} else if (empty($tablename) && $module == 'Documents') {
|
|
$tablename = 'vtiger_senotesrel';
|
|
$tabIndex = 'notesid';
|
|
$relIndex = 'crmid';
|
|
} else if (empty($tablename)) {
|
|
//Fallback to vtiger_crmentityrel if both focus and relationfieldid is empty
|
|
$tablename = 'vtiger_crmentityrel';
|
|
$tabIndex = 'crmid';
|
|
$relIndex = 'crmid';
|
|
}
|
|
//END
|
|
|
|
if ($tablename == 'vtiger_crmentityrel') {
|
|
$sql .= ' LEFT JOIN vtiger_activity ON vtiger_activity.activityid = vtiger_crmentity.crmid ';
|
|
$sql .= " INNER JOIN $tablename ON ($tablename.relcrmid = vtiger_crmentity.crmid OR $tablename.crmid = vtiger_crmentity.crmid)
|
|
WHERE ($tablename.crmid IN (" . generateQuestionMarks($recordIds) . ") AND ($tablename.relmodule = '" . $module . "'))
|
|
OR ($tablename.relcrmid IN (" . generateQuestionMarks($recordIds) . ") AND ($tablename.module = '" . $module . "'))";
|
|
foreach ($recordIds as $key => $recordId) {
|
|
array_push($params, $recordId);
|
|
}
|
|
} else if ($module == "Contacts" && $this->getModuleName() == "Potentials") {
|
|
$tablename = 'vtiger_contpotentialrel';
|
|
$tabIndex = 'contactid';
|
|
$sql .= ' LEFT JOIN vtiger_activity ON vtiger_activity.activityid = vtiger_crmentity.crmid ';
|
|
$sql .= " INNER JOIN $tablename ON $tablename.$tabIndex = vtiger_crmentity.crmid
|
|
WHERE $tablename.potentialid IN (" . generateQuestionMarks($recordIds) . ")";
|
|
} else {
|
|
if (in_array($tablename, array('vtiger_senotesrel'))) {
|
|
$sql .= ' LEFT JOIN vtiger_activity ON vtiger_activity.activityid = vtiger_crmentity.crmid ';
|
|
}
|
|
$sql .= " INNER JOIN $tablename ON $tablename.$tabIndex = vtiger_crmentity.crmid
|
|
WHERE $tablename.$relIndex IN (" . generateQuestionMarks($recordIds) . ")";
|
|
}
|
|
} else {
|
|
$fieldModel = Vtiger_Field_Model::getInstance($relationFieldId);
|
|
$relatedModuleFocus = CRMEntity::getInstance($module);
|
|
$tablename = $fieldModel->get('table');
|
|
$relIndex = $fieldModel->get('column');
|
|
if ($tablename == $relatedModuleFocus->table_name) {
|
|
if ($this->getModuleName() == "Contacts" && $module == "Potentials") {
|
|
$tablename = 'vtiger_contpotentialrel';
|
|
$tabIndex = 'potentialid';
|
|
$sql .= " INNER JOIN $tablename ON $tablename.$tabIndex = vtiger_crmentity.crmid
|
|
WHERE $tablename.contactid IN (" . generateQuestionMarks($recordIds) . ")";
|
|
} else {
|
|
$tabIndex = $relatedModuleFocus->table_index;
|
|
$sql .= " INNER JOIN $tablename ON $tablename.$tabIndex = vtiger_crmentity.crmid
|
|
WHERE $tablename.$relIndex IN (" . generateQuestionMarks($recordIds) . ")";
|
|
}
|
|
|
|
} else {
|
|
$modulePrimaryTableName = $relatedModuleFocus->table_name;
|
|
$modulePrimaryTableIndex = $relatedModuleFocus->table_index;
|
|
$tabIndex = $relatedModuleFocus->tab_name_index[$tablename];
|
|
$sql .= " INNER JOIN $modulePrimaryTableName ON $modulePrimaryTableName.$modulePrimaryTableIndex = vtiger_crmentity.crmid
|
|
INNER JOIN $tablename ON $tablename.$tabIndex = $modulePrimaryTableName.$modulePrimaryTableIndex
|
|
WHERE $tablename.$relIndex IN (" . generateQuestionMarks($recordIds) . ")";
|
|
}
|
|
}
|
|
if ($nonAdminCheck) {
|
|
$sqlComponents = explode(" WHERE ", $sql);
|
|
if (empty($relatedModuleFocus)) $relatedModuleFocus = CRMEntity::getInstance($module);
|
|
$user = Users_Record_Model::getCurrentUserModel();
|
|
$relationAccessQuery = $relatedModuleFocus->getNonAdminAccessControlQuery($module, $user);
|
|
$sql = $sqlComponents[0] . $relationAccessQuery . " WHERE " . $sqlComponents[1];
|
|
}
|
|
|
|
$sql .= ' AND vtiger_crmentity.deleted = 0';
|
|
foreach ($recordIds as $key => $recordId) {
|
|
array_push($params, $recordId);
|
|
}
|
|
|
|
$result1 = $db->pquery($sql, $params);
|
|
$num_rows = $db->num_rows($result1); //should give doc crmid.
|
|
for ($j = 0; $j < $num_rows; $j++) {
|
|
$relatedIds[] = $db->query_result($result1, $j, 'crmid');
|
|
}
|
|
}
|
|
return $relatedIds;
|
|
} else {
|
|
return $relatedIds;
|
|
}
|
|
}
|
|
} |