Files
crm.clientright.ru/modules/ITS4YouMultiCompany/ITS4YouMultiCompany.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

465 lines
19 KiB
PHP

<?php
/*+**********************************************************************************
The content of this file is subject to the ITS4YouMultiCompany 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.
************************************************************************************/
include_once 'modules/Vtiger/CRMEntity.php';
class ITS4YouMultiCompany extends Vtiger_CRMEntity
{
public $table_name = 'its4you_multicompany4you';
public $table_index = 'companyid';
public $TAB_MODULE_NAME = "ITS4YouMultiCompany";
public $moduleName = 'ITS4YouMultiCompany';
public $parentName = 'Tools';
/**
* Mandatory table for supporting custom fields.
*/
public $customFieldTable = array('its4you_multicompany4youcf', 'companyid');
/**
* Mandatory for Saving, Include tables related to this module.
*/
public $tab_name = array('vtiger_crmentity', 'its4you_multicompany4you', 'its4you_multicompany4youcf');
/**
* Mandatory for Saving, Include tablename and tablekey columnname here.
*/
public $tab_name_index = array(
'vtiger_crmentity' => 'crmid',
'its4you_multicompany4you' => 'companyid',
'its4you_multicompany4youcf' => 'companyid'
);
/**
* Mandatory for Listing (Related listview)
*/
public $list_fields = array();
public $list_fields_name = array();
public $list_link_field = 'companyid';
// Make the field link to detail view
public $search_fields = array();
// For Popup listview and UI type support
public $search_fields_name = array();
public $popup_fields = array('company_no');
// For Popup window record selection
public $def_basicsearch_col = 'company_no';
// For Alphabetical search
public $def_detailview_recname = 'company_no';
// Column value to use on detail view record text display
public $mandatory_fields = array('company_no', 'assigned_user_id');
// Used when enabling/disabling the mandatory fields for the module.
// Refers to vtiger_field.fieldname values.
public $default_order_by = 'company_no';
public $default_sort_order = 'ASC';
public $log;
public $db;
public $column_fields;
public $LBL_MULTICOMPANY = 'Multi Company';
public function __construct()
{
global $log;
$this->log = $log;
$this->db = PearDatabase::getInstance();
$this->column_fields = getColumnFields($this->TAB_MODULE_NAME);
}
public static function checkAdminAccess($user)
{
return;
if (is_admin($user)) {
return;
}
echo "<table border='0' cellpadding='5' cellspacing='0' width='100%' height='450px'><tr><td align='center'>";
echo "<div style='border: 3px solid rgb(153, 153, 153); background-color: rgb(255, 255, 255); width: 55%; position: relative; z-index: 10000000;'>
<table border='0' cellpadding='5' cellspacing='0' width='98%'>
<tbody><tr>
<td rowspan='2' width='11%'><img src= " . vtiger_imageurl('denied.gif', $theme) . " ></td>
<td style='border-bottom: 1px solid rgb(204, 204, 204);' nowrap='nowrap' width='70%'>
<span class='genHeaderSmall'>" . vtranslate('LBL_PERMISSION') . "</span></td>
</tr>
<tr>
<td class='small' align='right' nowrap='nowrap'>
<a href='javascript:window.history.back();'>" . vtranslate('LBL_GO_BACK') . "</a><br>
</td>
</tr>
</tbody></table>
</div>";
echo "</td></tr></table>";
exit;
}
/**
* @throws Exception
*/
public function vtlib_handler($moduleName, $eventType)
{
include_once 'include/utils/utils.php';
include_once 'vtlib/Vtiger/Module.php';
include_once 'modules/ModTracker/ModTracker.php';
include_once 'modules/ModComments/ModComments.php';
switch ($eventType) {
case 'module.enabled':
case 'module.postupdate':
case 'module.postinstall':
$this->addCustomLinks();
break;
case 'module.disabled':
case 'module.preuninstall':
case 'module.preupdate':
$this->deleteCustomLinks();
break;
}
}
/**
* @throws Exception
*/
public function addCustomLinks()
{
$this->updateRelations();
$this->updateSettings();
$this->updateRelatedList();
$this->updateEventHandler();
$this->updateFields();
$this->handleCalendarRelatedToReferenceList();
Settings_MenuEditor_Module_Model::addModuleToApp($this->moduleName, $this->parentName);
ModTracker::enableTrackingForModule(getTabid($this->moduleName));
ModComments::addWidgetTo([$this->moduleName]);
}
/**
* [events, file, class, condition, dependOn, modules]
*/
public $registerEventHandler = [
['vtiger.entity.beforesave', 'modules/ITS4YouMultiCompany/ITS4YouUploadAttachment.php', 'ITS4YouMultiCompany_ITS4YouUploadAttachment_Handler',],
['vtiger.entity.aftersave', 'modules/ITS4YouMultiCompany/ITS4YouMultiCompanyHandler.php', 'ITS4YouMultiCompanyHandler',],
];
/**
* @param bool $register
*/
public function updateEventHandler($register = true)
{
$eventsManager = new VTEventsManager($this->db);
foreach ($this->registerEventHandler as $data) {
list($events, $fileName, $className, $condition, $dependOn, $modules) = $data;
$eventsManager->unregisterHandler($className);
if ($register) {
$condition = !empty($condition) ? $condition : '';
$dependOn = !empty($dependOn) ? $dependOn : '[]';
foreach ((array)$events as $event) {
$eventsManager->registerHandler($event, $fileName, $className, $condition, $dependOn);
foreach ((array)$modules as $module) {
$eventsManager->setModuleForHandler($module, $className);
}
}
}
}
}
/**
* @var array
* [Module, RelatedModule, RelatedLabel, RelatedActions, RelatedFunction]
*/
public $registerRelatedLists = array(
['ITS4YouMultiCompany', 'Documents', 'Documents', 'ADD,SELECT', 'get_attachments'],
);
public function retrieveRelatedList()
{
$result = $this->db->query('SELECT * FROM its4you_multicompany4you_cn_modules');
while($row = $this->db->fetchByAssoc($result)) {
$relatedModuleName = Vtiger_Functions::getModuleName($row['tab_id']);
if('Documents' === $relatedModuleName) {
continue;
}
$this->registerRelatedLists[] = ['ITS4YouMultiCompany', $relatedModuleName, $relatedModuleName, 'ADD'];
}
}
/**
* @param bool $register
*/
public function updateRelatedList($register = true)
{
foreach ($this->registerRelatedLists as $relatedList) {
$module = Vtiger_Module::getInstance($relatedList[0]);
$relatedModule = Vtiger_Module::getInstance($relatedList[1]);
if ($module && $relatedModule) {
$relatedLabel = isset($relatedList[2]) ? $relatedList[2] : $relatedModule->name;
$relatedActions = isset($relatedList[3]) ? $relatedList[3] : '';
$relatedFunction = isset($relatedList[4]) ? $relatedList[4] : 'get_related_list';
$field = isset($relatedList[5]) ? Vtiger_Field_Model::getInstance($relatedList[5], $relatedModule) : '';
$fieldId = $field ? $field->getId() : '';
$module->unsetRelatedList($relatedModule, $relatedLabel);
$module->unsetRelatedList($relatedModule, $relatedLabel, $relatedFunction);
if ($register) {
$module->setRelatedList($relatedModule, $relatedLabel, $relatedActions, $relatedFunction, $fieldId);
}
}
}
}
public function updateRelations()
{
/** @var ITS4YouMultiCompany_Module_Model $mcModuleModel */
$mcModuleModel = Vtiger_Module_Model::getInstance($this->moduleName);
$mcModuleModel->deleteRelations();
$mcModuleModel->updateRelations();
}
/**
* @throws Exception
*/
public function deleteCustomLinks()
{
$this->handleCalendarRelatedToReferenceList(false);
$this->updateRelatedList(false);
$this->updateEventHandler(false);
$this->updateSettings(false);
ModTracker::disableTrackingForModule(getTabid($this->moduleName));
ModComments::removeWidgetFrom([$this->moduleName]);
}
/**
* @param bool $register
* @throws Exception
*/
public function updateSettings($register = true)
{
$label = $this->LBL_MULTICOMPANY;
$blockId = getSettingsBlockId('LBL_OTHER_SETTINGS');
$sequenceResult = $this->db->pquery('SELECT max(sequence) AS max_seq FROM vtiger_settings_field WHERE blockid=?',
array($blockId)
);
$sequence = intval($this->db->query_result($sequenceResult, 0, 'max_seq')) + 1;
$this->db->pquery('DELETE FROM vtiger_settings_field WHERE name= ?', array($label));
if ($register) {
$this->db->pquery('INSERT INTO vtiger_settings_field(fieldid, blockid, name, iconpath, description, linkto, sequence) VALUES (?,?,?,?,?,?,?)',
array(
$this->db->getUniqueID('vtiger_settings_field'),
$blockId,
$label,
'modules/ITS4YouMultiCompany/img/multicompany4you.gif',
'Specify businness address for multiple companies',
'index.php?parent=Settings&module=ITS4YouMultiCompany&view=List',
$sequence,
)
);
}
}
public function updateFields()
{
$moduleModel = Vtiger_Module_Model::getInstance('ITS4YouMultiCompany');
$fieldNames = array('city', 'street', 'country');
foreach ($fieldNames as $fieldName) {
$fieldModel = Vtiger_Field_Model::getInstance($fieldName, $moduleModel);
if (!$fieldModel->isHeaderField()) {
$fieldModel->set('headerfield', 1);
$fieldModel->save();
}
}
}
public function handleCalendarRelatedToReferenceList($install = true)
{
$calendarModuleModel = Vtiger_Module_Model::getInstance('Calendar');
$fieldModel = Vtiger_Field_Model::getInstance('parent_id', $calendarModuleModel);
$result = $this->db->pquery('SELECT fieldtypeid FROM vtiger_ws_fieldtype WHERE uitype=?', array($fieldModel->get('uitype')));
$fieldType = $this->db->query_result($result, 0, 'fieldtypeid');
$result = $this->db->pquery('SELECT 1 FROM vtiger_ws_referencetype WHERE fieldtypeid=? and type=?', array($fieldType, 'ITS4YouMultiCompany'));
if ($install) {
if (!$this->db->num_rows($result)) {
$this->db->pquery('INSERT INTO vtiger_ws_referencetype(fieldtypeid,type) VALUES(?, ?)', array($fieldType, 'ITS4YouMultiCompany'));
$result = $this->db->pquery(
'SELECT 1 FROM vtiger_relatedlists WHERE tabid=? AND related_tabid=? AND name=? AND relationfieldid=?',
array(getTabid('ITS4YouMultiCompany'), getTabid('Calendar'), 'get_activities', $fieldModel->getId())
);
if (!$this->db->num_rows($result)) {
$module = Vtiger_Module::getInstance('ITS4YouMultiCompany');
$relModule = Vtiger_Module::getInstance('Calendar');
$module->setRelatedList($relModule, 'Activities', array('ADD'), 'get_activities', $fieldModel->getId());
}
}
} else {
if ($this->db->num_rows($result) > 0) {
$this->db->pquery('DELETE FROM vtiger_ws_referencetype WHERE fieldtypeid =? AND type =?', array($fieldType, 'ITS4YouMultiCompany'));
}
}
}
/**
* Function to handle the related list for the module.
* NOTE: Vtiger_Module::setRelatedList sets reference to this function in vtiger_relatedlists table
* if function name is not explicitly specified.
*/
public function get_related_list($id, $cur_tab_id, $rel_tab_id, $actions = false)
{
global $currentModule, $app_strings, $singlepane_view;
$parenttab = getParentTab();
$related_module = vtlib_getModuleNameById($rel_tab_id);
$other = CRMEntity::getInstance($related_module);
// Some standard module class doesn't have required variables
// that are used in the query, they are defined in this generic API
vtlib_setup_modulevars($currentModule, $this);
vtlib_setup_modulevars($related_module, $other);
$singular_modname = 'SINGLE_' . $related_module;
$button = '';
if ($actions) {
if (is_string($actions)) {
$actions = explode(',', strtoupper($actions));
}
if (in_array('SELECT', $actions) && isPermitted($related_module, 4, '') == 'yes') {
$button .= "<input title='" . getTranslatedString('LBL_SELECT') . " " . getTranslatedString($related_module) . "' class='crmbutton small edit' " .
" type='button' onclick=\"return window.open('index.php?module=$related_module&return_module=$currentModule&action=Popup&popuptype=detailview&select=enable&form=EditView&form_submit=false&recordid=$id&parenttab=$parenttab','test','width=640,height=602,resizable=0,scrollbars=0');\"" .
" value='" . getTranslatedString('LBL_SELECT') . " " . getTranslatedString($related_module, $related_module) . "'>&nbsp;";
}
if (in_array('ADD', $actions) && isPermitted($related_module, 1, '') == 'yes') {
$button .= "<input type='hidden' name='createmode' id='createmode' value='link' />" .
"<input title='" . getTranslatedString('LBL_ADD_NEW') . " " . getTranslatedString($singular_modname) . "' class='crmbutton small create'" .
" onclick='this.form.action.value=\"EditView\";this.form.module.value=\"$related_module\"' type='submit' name='button'" .
" value='" . getTranslatedString('LBL_ADD_NEW') . " " . getTranslatedString($singular_modname, $related_module) . "'>&nbsp;";
}
}
// To make the edit or del link actions to return back to same view.
if ($singlepane_view == 'true') {
$returnset = "&return_module=$currentModule&return_action=DetailView&return_id=$id";
} else {
$returnset = "&return_module=$currentModule&return_action=CallRelatedList&return_id=$id";
}
$more_relation = '';
if (!empty($other->related_tables)) {
foreach ($other->related_tables as $tname => $relmap) {
$query .= ", $tname.*";
// Setup the default JOIN conditions if not specified
if (empty($relmap[1])) {
$relmap[1] = $other->table_name;
}
if (empty($relmap[2])) {
$relmap[2] = $relmap[0];
}
$more_relation .= " LEFT JOIN " . $tname . " ON " . $tname . "." . $relmap[0] . " = " . $relmap[1] . "." . $relmap[2] . " ";
}
}
$query = "SELECT vtiger_crmentity.*, " . $other->table_name . ".*
FROM " . $other->table_name . "
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = " . $other->table_name . "." . $other->table_index . "
" . $more_relation . "
LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid
LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid
WHERE vtiger_crmentity.deleted = 0 AND " . $other->table_name . ".its4you_company = '" . $id . "'";
$return_value = GetRelatedList($currentModule, $related_module, $other, $query, $button, $returnset);
if ($return_value == null) {
$return_value = array();
}
$return_value['CUSTOM_BUTTON'] = $button;
return $return_value;
}
/**
* @return array
*/
public function getRequirementValidations()
{
return array(
array(
'type' => 'fields',
'label' => vtranslate('LBL_INTEGRATION', $this->moduleName),
'function' => 'getRequirementIntegration',
),
);
}
/**
* @throws Exception
*/
public function getRequirementIntegration()
{
$info = array();
$result = $this->db->query('SELECT * FROM its4you_multicompany4you_cn_modules');
while($row = $this->db->fetchByAssoc($result)) {
$moduleName = Vtiger_Functions::getModuleName($row['tab_id']);
$moduleModel = Vtiger_Module_Model::getInstance($moduleName);
$message = '';
$field = Vtiger_Field_Model::getInstance('its4you_company', $moduleModel);
$data = array(
'module' => $moduleName,
'field' => $field ? vtranslate($field->get('label'), $moduleName) : '',
'reference_module' => $field ? implode(',', $field->getReferenceList()) : '',
);
if(!in_array('ITS4YouMultiCompany', explode(',', $data['reference_module']))) {
$message = 'LBL_MISSING_REFERENCE_MODULE';
}
if (!$field || 2 !== intval($field->get('presence'))) {
$message = 'LBL_MISSING_COMPANY_FIELD';
}
$data['validate'] = empty($message);
$data['validate_message'] = vtranslate($message, $this->moduleName);
$info[] = $data;
}
return $info;
}
public function getRequirementHeaders() {
return array(
vtranslate('LBL_MODULE', $this->moduleName) => 'module',
vtranslate('LBL_COMPANY_FIELD', $this->moduleName) => 'field',
vtranslate('LBL_REFERENCE_MODULE', $this->moduleName) => 'reference_module',
);
}
}