- 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.
495 lines
18 KiB
PHP
495 lines
18 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.
|
|
************************************************************************************/
|
|
|
|
class ITS4YouMultiCompany_CustomRecordNumbering_Model extends Vtiger_Module_Model
|
|
{
|
|
protected $focus;
|
|
protected $db;
|
|
protected $numberTable;
|
|
protected $numberColumn;
|
|
|
|
/**
|
|
* Function to ger Supported modules for Custom record numbering
|
|
* @return array list of supported modules <Vtiger_Module_Model>
|
|
*/
|
|
public static function getSupportedModules()
|
|
{
|
|
$db = PearDatabase::getInstance();
|
|
$modulesModels = array();
|
|
$sql = "SELECT tabid, name, tab_id FROM vtiger_tab LEFT JOIN its4you_multicompany4you_cn_modules ON tab_id=tabid WHERE isentitytype = ? AND presence = ? AND tabid IN (SELECT DISTINCT tabid FROM vtiger_field WHERE uitype = ?) ORDER BY name ASC";
|
|
$result = $db->pquery($sql, array(1, 0, 4));
|
|
while ($row = $db->fetchByAssoc($result)) {
|
|
if ($row['name'] != 'ITS4YouMultiCompany') {
|
|
if (vtlib_isModuleActive($row['name'])) {
|
|
$modulesModels[$row['tabid']] = $row;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $modulesModels;
|
|
}
|
|
|
|
public static function getAllowedModules()
|
|
{
|
|
$db = PearDatabase::getInstance();
|
|
|
|
$sql = "SELECT tabid, name FROM its4you_multicompany4you_cn_modules INNER JOIN vtiger_tab ON tabid=tab_id WHERE isentitytype = ? AND presence = ?";
|
|
|
|
$result = $db->pquery($sql, array(1, 0));
|
|
$numOfRows = $db->num_rows($result);
|
|
$modulesModels = array();
|
|
for ($i = 0; $i < $numOfRows; $i++) {
|
|
$tabId = $db->query_result($result, $i, 'tabid');
|
|
$modulesModels[$tabId] = ITS4YouMultiCompany_CustomRecordNumbering_Model::getInstance($db->query_result($result, $i, 'name'), $tabId);
|
|
}
|
|
|
|
return $modulesModels;
|
|
}
|
|
|
|
/**
|
|
* @param string $moduleName
|
|
* @param int|false $tabId
|
|
* @return ITS4YouMultiCompany_CustomRecordNumbering_Model
|
|
*/
|
|
public static function getInstance($moduleName, $tabId = false)
|
|
{
|
|
$moduleModel = new self();
|
|
$moduleModel->db = PearDatabase::getInstance();
|
|
$moduleModel->name = $moduleName;
|
|
|
|
if ($tabId) {
|
|
$moduleModel->id = $tabId;
|
|
}
|
|
|
|
return $moduleModel;
|
|
}
|
|
|
|
public static function getCompanyForUser($user_id)
|
|
{
|
|
return self::getCompanyForRole(self::getCompanyRoleForUser($user_id));
|
|
}
|
|
|
|
public static function getCompanyForRole($role_id)
|
|
{
|
|
$adb = PearDatabase::getInstance();
|
|
$companyid = '';
|
|
$res = $adb->pquery("SELECT companyid FROM its4you_multicompany4you
|
|
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid = its4you_multicompany4you.companyid
|
|
WHERE its4you_multicompany4you.mc_role=? AND vtiger_crmentity.deleted = 0", array($role_id));
|
|
if ($adb->num_rows($res) > 0) {
|
|
$row = $adb->fetchByAssoc($res);
|
|
$companyid = $row['companyid'];
|
|
}
|
|
return $companyid;
|
|
}
|
|
|
|
public static function getCompanyRoleForUser($user_id = '')
|
|
{
|
|
if ($user_id == '') {
|
|
global $current_user;
|
|
$user_id = $current_user->id;
|
|
}
|
|
|
|
$adb = PearDatabase::getInstance();
|
|
$foundrole = '';
|
|
$roleres = $adb->pquery("SELECT parentrole FROM vtiger_user2role INNER JOIN vtiger_role ON vtiger_role.roleid=vtiger_user2role.roleid WHERE userid=?", array($user_id));
|
|
if ($adb->num_rows($roleres) > 0) {
|
|
$row = $adb->fetchByAssoc($roleres);
|
|
$parentrole = $row['parentrole'];
|
|
$UsedRoles = array();
|
|
$used_roles_res = $adb->pquery("SELECT parentrole FROM vtiger_role WHERE roleid IN (SELECT mc_role FROM its4you_multicompany4you WHERE mc_role IS NOT NULL)");
|
|
while ($used_roles_row = $adb->fetchByAssoc($used_roles_res)) {
|
|
$UsedRoles[] = $used_roles_row['parentrole'];
|
|
}
|
|
|
|
$Exploded = explode('::', $parentrole);
|
|
$nextrole = '';
|
|
foreach ($Exploded as $addtorole) {
|
|
if ($nextrole != '') {
|
|
$nextrole .= '::';
|
|
}
|
|
$nextrole .= $addtorole;
|
|
if (in_array($nextrole, $UsedRoles)) {
|
|
$foundrole = $addtorole;
|
|
}
|
|
}
|
|
}
|
|
return $foundrole;
|
|
}
|
|
|
|
public static function getUsedRoles()
|
|
{
|
|
$adb = PearDatabase::getInstance();
|
|
$UsedRoles = array();
|
|
$used_roles_res = $adb->pquery("SELECT roleid, parentrole FROM vtiger_role WHERE roleid IN (SELECT mc_role FROM its4you_multicompany4you INNER JOIN vtiger_crmentity on vtiger_crmentity.crmid = its4you_multicompany4you.companyid WHERE its4you_multicompany4you.mc_role IS NOT NULL AND vtiger_crmentity.deleted = ?)", array(0));
|
|
while ($used_roles_row = $adb->fetchByAssoc($used_roles_res)) {
|
|
$roleId = $used_roles_row['roleid'];
|
|
$UsedRoles[$roleId] = Settings_Roles_Record_Model::getInstanceById($roleId);
|
|
}
|
|
|
|
return $UsedRoles;
|
|
}
|
|
|
|
public function getEditNumberingUrl()
|
|
{
|
|
return "index.php?module=ITS4YouMultiCompany&view=EditNumbering";
|
|
}
|
|
|
|
/**
|
|
* Function to get module custom numbering data
|
|
* @return <Array> data of custom numbering data
|
|
*/
|
|
public function getModuleCustomNumberingData($companyId = '')
|
|
{
|
|
$adb = PearDatabase::getInstance();
|
|
if ($companyId < 1) {
|
|
$companyId = $_REQUEST['record'];
|
|
}
|
|
$result = $adb->pquery("SELECT start_id, cur_id, prefix FROM its4you_multicompany4you_cn WHERE tab_id=? AND companyid=? AND active = 1", array(getTabId($this->getName()), $companyId));
|
|
return $adb->fetchByAssoc($result);
|
|
}
|
|
|
|
/**
|
|
* Function to set Module sequence
|
|
* @param string $companyid Id of company
|
|
* @return array <Array> result of success
|
|
*/
|
|
public function setModuleSequence($companyid = '')
|
|
{
|
|
if ($companyid < 1) {
|
|
$companyid = $_REQUEST['companyid'];
|
|
}
|
|
|
|
$moduleName = $this->getName();
|
|
$prefix = $this->get('prefix');
|
|
$sequenceNumber = $this->get('sequenceNumber');
|
|
|
|
$status = $this->setModuleSeqNumber('configure', $moduleName, $prefix, $sequenceNumber, $companyid);
|
|
|
|
$success = array('success' => $status);
|
|
if (!$status) {
|
|
$db = PearDatabase::getInstance();
|
|
$result = $db->pquery("SELECT cur_id FROM its4you_multicompany4you_cn WHERE tab_id = ? AND companyid=? AND prefix = ?", array(getTabId($moduleName), $companyid, $prefix));
|
|
$success['sequenceNumber'] = $db->query_result($result, 0, 'cur_id');
|
|
}
|
|
|
|
return $success;
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
public function setModuleSeqNumber($mode, $module, $req_str = '', $req_no = '', $companyId = 0)
|
|
{
|
|
global $adb;
|
|
$module = $this->getName();
|
|
$tabId = getTabId($module);
|
|
//when we configure the invoice number in Settings this will be used
|
|
if ('configure' === $mode && !empty($req_no)) {
|
|
$check = $adb->pquery('SELECT cur_id FROM its4you_multicompany4you_cn WHERE tab_id=? AND prefix = ? AND companyid=?',
|
|
array($tabId, $req_str, $companyId)
|
|
);
|
|
|
|
if (!$adb->num_rows($check)) {
|
|
$adb->pquery('UPDATE its4you_multicompany4you_cn SET active=0 where tab_id=? and active=1 AND companyid=?',
|
|
array($tabId, $companyId)
|
|
);
|
|
$adb->pquery('INSERT into its4you_multicompany4you_cn values(?,?,?,?,?,?)',
|
|
array($companyId, $tabId, $req_str, $req_no, $req_no, 1)
|
|
);
|
|
|
|
return true;
|
|
} else {
|
|
$num_check = $adb->query_result($check, 0, 'cur_id');
|
|
|
|
if ($req_no < $num_check) {
|
|
|
|
return false;
|
|
} else {
|
|
$adb->pquery('UPDATE its4you_multicompany4you_cn SET active=0 WHERE active=1 AND tab_id=? AND companyid=?',
|
|
array($tabId, $companyId)
|
|
);
|
|
$adb->pquery('UPDATE its4you_multicompany4you_cn SET cur_id=?, active = 1 WHERE prefix=? AND tab_id=? AND companyid=?',
|
|
array($req_no, $req_str, $tabId, $companyId)
|
|
);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
} elseif ('increment' === $mode) {
|
|
$check = $adb->pquery('SELECT cur_id, prefix FROM its4you_multicompany4you_cn WHERE tab_id=? AND active = 1 AND companyid=?',
|
|
array($tabId, $companyId)
|
|
);
|
|
$checkData = $adb->fetchByAssoc($check, 0);
|
|
|
|
if (empty($checkData['prefix'])) {
|
|
return false;
|
|
}
|
|
|
|
$prefix = str_replace(
|
|
array('$year$', '$month$', '$week$', '$day$'),
|
|
array(date('Y'), date('m'), date('W'), date('d')),
|
|
$checkData['prefix']
|
|
);
|
|
$cur_id = $checkData['cur_id'];
|
|
$prev_inv_no = $prefix . $cur_id;
|
|
$strip = strlen($cur_id) - strlen($cur_id + 1);
|
|
|
|
if ($strip < 0) {
|
|
$strip = 0;
|
|
}
|
|
|
|
$temp = str_repeat('0', $strip);
|
|
$req_no .= $temp . ($cur_id + 1);
|
|
$adb->pquery('UPDATE its4you_multicompany4you_cn SET cur_id=? WHERE cur_id=? AND active=1 AND tab_id=? AND companyid=?',
|
|
array($req_no, $cur_id, $tabId, $companyId)
|
|
);
|
|
|
|
return decode_html($prev_inv_no);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param string $moduleName
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
public function decrementStandardNumbering($moduleName)
|
|
{
|
|
$adb = PearDatabase::getInstance();
|
|
$result = $adb->pquery(
|
|
'SELECT cur_id FROM vtiger_modentity_num WHERE semodule=? AND active=?',
|
|
array($moduleName, 1)
|
|
);
|
|
$stringVal = $adb->query_result($result, 0, 'cur_id');
|
|
$intVal = intval(ltrim($stringVal, '0')) - 1;
|
|
$strip = strlen(strval($stringVal)) - strlen(strval($intVal));
|
|
|
|
if ($strip < 0) {
|
|
$strip = 0;
|
|
}
|
|
|
|
$currentId = str_repeat('0', $strip) . $intVal;
|
|
|
|
if ($currentId) {
|
|
$adb->pquery(
|
|
'UPDATE vtiger_modentity_num SET cur_id=? WHERE semodule=? AND active=?',
|
|
array($currentId, $moduleName, 1)
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to update record sequences which are under this module
|
|
* @return <Array> result of success
|
|
*/
|
|
public function updateRecordsWithSequence($companyid)
|
|
{
|
|
//return $this->getFocus()->updateMissingSeqNumber($this->getName());
|
|
return $this->updateMissingSeqNumber($this->getName(), $companyid);
|
|
}
|
|
|
|
private function updateMissingSeqNumber($module, $companyid)
|
|
{
|
|
global $log, $adb;
|
|
|
|
vtlib_setup_modulevars($module, $this);
|
|
|
|
if (!$this->isModuleSequenceConfigured($module, $companyid)) {
|
|
return;
|
|
}
|
|
|
|
$tabid = getTabid($module);
|
|
$fieldinfo = $adb->pquery("SELECT * FROM vtiger_field WHERE tabid = ? AND uitype = 4", array($tabid));
|
|
|
|
$returninfo = array();
|
|
|
|
if ($fieldinfo && $adb->num_rows($fieldinfo)) {
|
|
// TODO: We assume the following for module sequencing field
|
|
// 1. There will be only field per module
|
|
// 2. This field is linked to module base table column
|
|
$fld_table = $adb->query_result($fieldinfo, 0, 'tablename');
|
|
$fld_column = $adb->query_result($fieldinfo, 0, 'columnname');
|
|
|
|
if ($fld_table == $this->table_name) {
|
|
$records = $adb->query("SELECT $this->table_index AS recordid FROM $this->table_name " .
|
|
"WHERE $fld_column = '' OR $fld_column is NULL");
|
|
|
|
if ($records && $adb->num_rows($records)) {
|
|
$returninfo['totalrecords'] = $adb->num_rows($records);
|
|
$returninfo['updatedrecords'] = 0;
|
|
|
|
$modseqinfo = $this->getModuleSeqInfo($module, $companyid);
|
|
$prefix = str_replace(array('$year$', '$month$', '$week$', '$day$'), array(date('Y'), date('m'), date('W'), date('d')), $modseqinfo[0]);
|
|
$cur_id = $modseqinfo[1];
|
|
|
|
$old_cur_id = $cur_id;
|
|
while ($recordinfo = $adb->fetch_array($records)) {
|
|
$value = "$prefix" . "$cur_id";
|
|
$adb->pquery("UPDATE $fld_table SET $fld_column = ? WHERE $this->table_index = ?", array($value, $recordinfo['recordid']));
|
|
// $cur_id += 1;
|
|
|
|
$strip = strlen($cur_id) - strlen($cur_id + 1);
|
|
if ($strip < 0) {
|
|
$strip = 0;
|
|
}
|
|
$temp = str_repeat("0", $strip);
|
|
$cur_id = $temp . ($cur_id + 1);
|
|
|
|
$returninfo['updatedrecords'] = $returninfo['updatedrecords'] + 1;
|
|
}
|
|
if ($old_cur_id != $cur_id) {
|
|
$adb->pquery("UPDATE its4you_multicompany4you_cn set cur_id=? where tab_id=? and active=1 AND companyid=?", array($cur_id, getTabId($module), $companyid));
|
|
}
|
|
}
|
|
} else {
|
|
$log->fatal("Updating Missing Sequence Number FAILED! REASON: Field table and module table mismatching.");
|
|
}
|
|
}
|
|
return $returninfo;
|
|
}
|
|
|
|
private function isModuleSequenceConfigured($module, $companyid)
|
|
{
|
|
$adb = PearDatabase::getInstance();
|
|
$result = $adb->pquery('SELECT 1 FROM its4you_multicompany4you_cn WHERE tab_id = ? AND active = 1 AND companyid=?', array(getTabId($module), $companyid));
|
|
if ($result && $adb->num_rows($result) > 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private function getModuleSeqInfo($module, $companyid)
|
|
{
|
|
global $adb;
|
|
$check = $adb->pquery("select cur_id, prefix from its4you_multicompany4you_cn where tab_id=? and active = 1 AND companyid=?", array(getTabId($module), $companyid));
|
|
$prefix = $adb->query_result($check, 0, 'prefix');
|
|
$curid = $adb->query_result($check, 0, 'cur_id');
|
|
return array($prefix, $curid);
|
|
}
|
|
|
|
public function getNumberFieldInfo()
|
|
{
|
|
$tabId = getTabid($this->name);
|
|
$adb = PearDatabase::getInstance();
|
|
$result = $adb->pquery('SELECT tablename, columnname FROM vtiger_field WHERE tabid = ? AND uitype = ?', array($tabId, 4));
|
|
|
|
if ($adb->num_rows($result)) {
|
|
return $adb->query_result_rowdata($result);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function isPrimaryTable($table)
|
|
{
|
|
return $this->focus->table_name === $table;
|
|
}
|
|
|
|
public function retrieveFocus()
|
|
{
|
|
$this->focus = CRMEntity::getInstance($this->name);
|
|
}
|
|
|
|
public function retrieveNumberFieldInfo()
|
|
{
|
|
$info = $this->getNumberFieldInfo();
|
|
|
|
$this->numberTable = $info['tablename'];
|
|
$this->numberColumn = $info['columnname'];
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getNumberColumn()
|
|
{
|
|
return $this->numberColumn;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getNumberTable()
|
|
{
|
|
return $this->numberTable;
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
public function updateEmptyCompanyField()
|
|
{
|
|
$this->retrieveFocus();
|
|
$this->retrieveNumberFieldInfo();
|
|
|
|
if ($this->isPrimaryTable($this->getNumberTable()) && $this->isCompanyColumnExists()) {
|
|
$recordsResult = $this->db->query(sprintf('SELECT %s AS recordid FROM %s WHERE its4you_company="" OR its4you_company is NULL', $this->focus->table_index, $this->focus->table_name));
|
|
|
|
while ($row = $this->db->fetchByAssoc($recordsResult)) {
|
|
if (!isRecordExists($row['recordid'])) {
|
|
continue;
|
|
}
|
|
|
|
$recordModel = Vtiger_Record_Model::getInstanceById($row['recordid']);
|
|
$companyId = self::getCompanyForUser($recordModel->get('assigned_user_id'));
|
|
|
|
if ($companyId) {
|
|
$this->updateCompanyField($recordModel, $companyId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
public function updateNumberField($recordModel, $companyId)
|
|
{
|
|
$next = $this->setModuleSeqNumber('increment', $this->name, '', '', $companyId);
|
|
|
|
if ($next) {
|
|
$this->db->pquery(sprintf('UPDATE %s SET %s=? WHERE %s=?', $this->focus->table_name, $this->getNumberColumn(), $this->focus->table_index), [$next, $recordModel->getId()]);
|
|
$this->decrementStandardNumbering($this->name);
|
|
}
|
|
}
|
|
|
|
public function isCompanyColumnExists()
|
|
{
|
|
return columnExists('its4you_company', $this->focus->table_name);
|
|
}
|
|
|
|
public function updateCompanyField($recordModel, $companyId)
|
|
{
|
|
$this->db->pquery(sprintf('UPDATE %s SET its4you_company=? WHERE %s=?', $this->focus->table_name, $this->focus->table_index), [$companyId, $recordModel->getId()]);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|