Files
crm.clientright.ru/modules/ITS4YouMobileApp/models/DetailRecord.php
Fedor ac7467f0b4 Major CRM updates: AI Assistant, Court Status API, S3 integration improvements, and extensive file storage system
- 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.
2025-10-16 11:17:21 +03:00

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;
}
}
}