1,'mardi'=>2,'mercredi'=>3,'jeudi'=>4,'vendredi'=>5,'samedi'=>6,'dimanche'=>7, 'cðÁÐÇ'=>3,'cðÁÐÇðÁð┤ð░'=>3,'cÐâð▒ð¥Ðéð░'=>6,'cð▒'=>6,'cÐâð▒'=>6,'cð▓'=>6,'cÐÇðÁ'=>3,'cÐÇðÁð┤'=>3,'cÐÇ'=>3,'cÐÇð┤'=>3,'cÐâð▒ð▒ð¥Ðéð░'=>6, //ð╗ð░Ðéð©ð¢Ðüð║ð©ðÁ ð▒Ðâð║ð▓Ðï C 'ð¢ð┤'=>7,'ð¢ðÁð┤ið╗ÐÅ'=>7,'ð¢ðÁð┤'=>7,'ð┐ð¥ð¢ðÁð┤Ðûð╗ð¥ð║'=>1,'ð▓Ðûð▓Ðéð¥ÐÇð¥ð║'=>2,'ÐüðÁÐÇ'=>3,'ÐüðÁÐÇðÁð┤ð░'=>3,'ÐçðÁÐéð▓ðÁÐÇ'=>4,'ð┐\'ÐÅÐéð¢ð©ÐåÐÅ'=>5,'ÐüÐâð▒ð¥Ðéð░'=>6,'Ðüð▓'=>6,'ð▓ð¥Ðüð║ÐÇðÁÐüðÁð¢ÐîðÁ'=>7, 'ð┐ð¢ð┤'=>1,'ð┐ð¥ð¢'=>1,'ð┐ð¥'=>1,'ÐçðÁÐé'=>4,'ÐçðÁÐéð▓'=>4,'ð┐Ðéð¢'=>5,'ð┐ÐÅÐé'=>5,'ð┐ÐÅÐéð¢'=>5,'ÐüÐâð▒'=>6,'ð▓Ðüð║ÐÇ'=>7,'ð▓Ðüð║'=>7,'ð▓ð¥Ðüð║ÐÇ'=>7,'ð▓ð¥Ðü'=>7,'ð▓Ðéð¥ÐÇ'=>2,'ð▓Ðéð¥'=>2,'ÐüÐÇðÁ'=>3,'ÐüÐÇðÁð┤'=>3,'ÐüÐÇð┤'=>3, 'ð┐ð¥ð¢ðÁð┤ðÁð╗Ðîð¢ð©ð║'=>1,'ÐçðÁÐéð▓ðÁÐÇð│'=>4,'ÐüÐÇðÁð┤ð░'=>3,'ð┐ÐÅÐéð¢ð©Ðåð░'=>5,'ÐüÐâð▒ð▒ð¥Ðéð░'=>6,'ð▓ð¥Ðüð║ÐÇðÁÐüðÁð¢ð©ðÁ'=>7, 'ð┐ð¢'=>1,'ð▓Ðé'=>2,'ÐüÐÇ'=>3,'ÐçÐé'=>4,'ð┐Ðé'=>5,'Ðüð▒'=>6,'ð▓Ðü'=>7, //castellano|catala 'lunes'=>1,'martes'=>2,'mi├®rcoles'=>3,'mi|rcoles'=>3,'mi|r'=>3,'mi|'=>3,'miercoles'=>3,'jueves'=>4,'vier'=>5,'viernes'=>5,'s?bado'=>6,'sabado'=>6,'s|b'=>6,'s|bado'=>6,'domingo'=>7, 'dilluns'=>1,'dimarts'=>2,'dimecres'=>3,'dijous'=>4,'divendres'=>5,'dissabte'=>6,'diumenge'=>7, 'dil'=>1,'dim'=>2,'dimec'=>3,'dij'=>4,'div'=>5,'dis'=>6,'diu'=>7,'dium'=>7, 'lun'=>1,'mar'=>2,'mi├®'=>3,'mie'=>3,'mier'=>3,'mi├®r'=>3,'jue'=>4,'vie'=>5,'s?b'=>6,'sab'=>6,'dom'=>7, //english 'mon'=>1,'tue'=>2,'wed'=>3,'thu'=>4,'fri'=>5,'sat'=>6,'sun'=>7, 'monday'=>1,'tuesday'=>2,'wednesday'=>3,'thursday'=>4,'friday'=>5,'saturday'=>'6','sunday'=>'7', 'pon' => 1, 'pn' => 1, 'po' => 1, 'wtor'=>2,'wto'=>2,'wt'=>2,'czw' => 4, 'czwt' => 4, 'pt' => 5, 'piat' => 5,'pi─àt' => 5, 'ptn' => 5, 'sob' => 6, 'nd' => 7, 'wk' => 7, 'niedz' => 7, 'ndz' => 7, 'poniedzia┼éek' => 1,'wtorek'=>2, 'czwartek' => 4, '┼øroda' => 3, 'pi─àtek' => 5, 'piatek'=>5,'sobota' => 6, 'niedziela' => 7, 'pn' => 1, 'wt' => 2, 'sr' => 3, 'cz' => 4, 'pt' => 5, 'sb' => 6, 'nd' => 7, ); //ð© Ðé ð┤. ð£ð¥ðÂð¢ð¥ ð┤ð¥ð▒ð░ð▓ð╗ÐÅÐéÐî ð┤ð¢ð©. public $aDayOffTitles = array('ð▓ÐïÐàð¥ð┤ð¢ð¥ð╣','cerrado','closed','ð▓ÐïÐà.','ð▓ÐïÐà','ðÀð░ð║ÐÇÐïÐéð¥','ferm','wychodni', 'zamkni─Öte', 'wye.', 'wye', ); //const PREG_STREET = '/(Ðâð╗\.|^Ðâð╗ | Ðâð╗$| ð│\.|^ð│\.|ð│ð¥ÐÇð¥ð┤| Ðê\.|^Ðê\.|Ðêð¥ÐüÐüðÁ|ð┐ÐÇ\.|ð┐ÐÇð¥ðÁðÀð┤|ð┐ÐÇ\-ð┤|ð┐ÐÇð¥Ðüð┐\.|ð┐ÐÇð¥Ðüð┐ðÁð║Ðé|ð┐ðÁÐÇ\.| ð┐\.|ð┐ðÁÐÇðÁÐâð╗ð¥ð║|ð¢ð░ð▒\.|ð▒Ðâð╗Ðîð▓ð░ÐÇ| ð▒\.|ð▒Ðâð╗\.)/'; const PREG_STREET = '/(^|\s)(ð▒?Ðâð╗|Ðêð¥?Ðü?|ð┐ÐÇ|ð┐ÐÇð¥Ðüð┐|ð┐ðÁÐÇ|ð¢ð░ð▒|ð┐ÐÇ\-ðÀ?ð┤|ð┐ÐÇ\-ð║?Ðé|ð▒|Ðâð╗ð©Ðåð░|Ðêð¥ÐüÐü?[ðÁÐì]|ð┐ÐÇð¥ðÁðÀð┤|ð┐ÐÇð¥Ðüð┐ðÁð║Ðé|ð┐ðÁÐÇðÁÐâð╗ð¥ð║|ð▒Ðâð╗Ðîð▓ð░ÐÇ)(\.|,|\s|$)/iu'; const PREG_ZIPCODE= '/^\d{5,7}$/u'; const WORKTIME_FULL = 0; const WORKTIME_EDIT = 1; const WORKTIME_SHORT= 2; const WORKTIME_SHORT_PLUS= 3; public $aValidPostFields = array('title','value','metro_id','zipcode','street','home','build','corp','office','orient','phone','fax','contact_face','working_time','communication','lng','lat'); public function __construct() { } protected function execute( $aParams ) { if ( isset( $aParams['by_address'] ) && $aParams['by_address'] = trim( $aParams['by_address'] ) ) { $aParams['by_address'] = is_numeric($aParams['by_address'])?mysql_real_escape_string($aParams['by_address']).'%': '%'.trim( preg_replace( self::PREG_STREET , '', mysql_real_escape_string(str_replace(' ','%',$aParams['by_address'])) ) ).'%'; } $sQueryConditiones = ( !empty( $aParams[$this->_sPrimaryKey])?' AND FA.'.$this->_sPrimaryKey.' = ' . (int)$aParams[$this->_sPrimaryKey] : '' ) . ( !empty( $aParams['firm_id']) ?' AND FA.firm_id ' . ( is_array($aParams['firm_id'])?' IN ( '.implode(',',$aParams['firm_id']).') ': '='.(int)$aParams['firm_id'] ) : '' ) . ( !empty( $aParams['city_id'] ) ?' AND FA.city_id = ' . (int)$aParams['city_id'] : '' ) . ( isset( $aParams['is_primary']) ?' AND FA.is_primary = ' . (int)$aParams['is_primary'] : '' ) . ( !empty( $aParams['yes_location'] )?' AND ( lat != "" AND lng != "" '.(!empty( $aParams['force_ids'] )?' OR address_id IN ('.implode(',',$aParams['force_ids']).') ':'').' ) ':'' ). ( !empty( $aParams['by_address'] ) ?' AND value LIKE "' . $aParams['by_address'] . '"' : '' ); if ( !trim( $sQueryConditiones ) ) { return $this->_oAdo->Execute('SELECT 1'); } $sSQL = 'SELECT ' . ( isset( $aParams['select_fields'] ) ? $aParams['selected_fields'] : ' FA.* ' ) . ' '.( !empty( $aParams['join_metro'] ) ? ', M.name_ru AS metroName ' : '' ).' FROM '.$this->_sTableName.' AS FA ' . ( !empty( $aParams['join_metro'] ) ? ' LEFT JOIN cataloxy_metro AS M USING(metro_id) ' : '' ). ' WHERE 1=1 ' . $sQueryConditiones . ' ORDER BY FA.is_primary DESC, FA.address_id DESC ' . ( !empty( $aParams['per_page'] ) ? ' LIMIT ' . $aParams['per_page'] : '' ); return $this->_oAdo->Execute( $sSQL ); } public function pasteValue( $aParams ) { return ($aParams['zipcode'] ? $aParams['zipcode'] . ', ': '' ) . (!preg_match( self::PREG_STREET, $aParams['street'] ) ?' Ðâð╗. ':'') . $aParams['street'] . ', ð┤. ' . $aParams['home'] . ( $aParams['build'] ? ', ÐüÐéÐÇ. ' . $aParams['build'] : '' ) . ( $aParams['corp'] ? ', ð║ð¥ÐÇð┐. ' . $aParams['corp'] : '' ) . ( $aParams['office'] ? ', ð¥Ðä. ' . $aParams['office'] : '' ); } /** * ðƒð¥ð╗ÐâÐçð©ÐéÐî Ðüð┐ð©Ðüð¥ð║ ÐéðÁð╗ðÁÐäð¥ð¢ð¥ð▓ ð┐ð¥ ÐâÐüð╗ð¥ð▓ð©ÐÅð╝ * @param $aParams * @param bool $bGetMixed --> ðÁÐüð╗ð© true, ð¢ðÁ ð▒Ðâð┤ðÁÐé ð│ÐÇÐâð┐ð┐ð©ÐÇð¥ð▓ð║ð© ð┐ð¥ Ðéð©ð┐Ðâ ð© ð░ð┤ÐÇðÁÐüÐâ - ð▓Ðïð┤ð░ÐüÐé ð┐ÐÇð¥ÐüÐéð¥ ð╝ð░ÐüÐüð©ð▓ ð¢ð¥ð╝ðÁÐÇð¥ð▓ * @return array|bool */ public function getPhones( $aParams, $bGetMixed = false ) { $aSQL = array(); foreach ( $aParams as $sField=>$mVal ) $aSQL[] = ' `'.$sField.'` '.(is_array( $mVal ) ? ' IN ('.implode(',',$mVal).') ' : ' = "'.(int)$mVal.'"'); if( !$aSQL ) { /* LEGACY_DEBUG_EMAIL_DISABLED: uncomment manually only if this real email notification is still required. mail(CONF_DEBUG_EMAIL,'critical error !!!',__CLASS__.', '.__FUNCTION__.','.__LINE__. print_r($aParams,1)); */ ((class_exists('DebugNotificationLogger', false) || ((@include_once __DIR__ . '/../../_lib/DebugNotificationLogNormalizer.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationPolicy.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationLogger.php'))) ? (DebugNotificationLogger::logEmail(CONF_DEBUG_EMAIL, '[ATTENTION_LEGACY_EMAIL_DISABLED] ' . ('critical error !!!'), __CLASS__.', '.__FUNCTION__.','.__LINE__. print_r($aParams,1), array( 'recipient_source' => 'CONF_DEBUG_EMAIL', 'notification_code' => 'legacy_debug_email_cataloxy_flex_php_inc_firmaddress_class_114', 'severity' => 'error', 'source_file' => __FILE__, 'source_line' => __LINE__, 'context' => array( 'attention_required' => true, 'legacy_email_disabled' => true, 'legacy_email_review_note' => 'Old direct mail() was disabled and commented. Review if real email notification is still required.', ), )) ? true : false) : false); die('err'); } $sSQL = 'SELECT * FROM cataloxy_firm_phone WHERE ' . implode( ' AND ', $aSQL ); if( !$aPhoneList = $this->_oAdo->GetArray( $sSQL ) ) return false; $aResult = array(); $aCopiesCheck = array(); $aByFirmsChecked= array(); foreach ( $aPhoneList as $aPhone ) { //ðÁÐüð╗ð© ÐìÐéð¥ Ðüð▒ð¥ÐÇ ÐéðÁð╗ðÁÐäð¥ð¢ð¥ð▓ Ðçð©ÐüÐéð¥ ð┐ð¥ Ðäð©ÐÇð╝ð░ð╝ ð© ð¢ÐâðÂð¢Ðï Ðâð¢ð©ð║ð░ð╗Ðîð¢ÐïðÁ - ð¢ðÁ ð┐ÐÇð¥ð▓ðÁÐÇÐÅðÁð╝ ð▒ð¥ð╗ÐîÐêðÁ, ðÁÐüð╗ð© ÐâðÂðÁ ð┐ð¥ Ðéð░ð║ð¥ð╣ Ðäð©ÐÇð╝ðÁ ð¢ð¥ð╝ðÁÐÇ ð▓ðÀÐÅÐé if( !empty($aByFirmsChecked[$aPhone['firm_id']]))continue; if( preg_match('/^\d+\)/u',$aPhone['number']) ) $aPhone['number'] = '('.$aPhone['number']; if( in_array( CONF_DOMAIN_ZONE,array('ru','ua','by','kz') ) ) $aPhone['number'] = str_replace('+8','8',$aPhone['number']); $sMultiKey=$aPhone['is_fax']?'faxes':'phones'; if( ( !defined('IS_CABINET')||!IS_CABINET ) && isset($aCopiesCheck[$sMultiKey][$aPhone['address_id'].''.$aPhone['number'].''.$aPhone['title']])) continue; $aCopiesCheck[$sMultiKey][$aPhone['number'].''.$aPhone['title']] = 1; if ( !$bGetMixed ) { $aResult[$aPhone['address_id']][$sMultiKey][] = $aPhone; } else { switch ( $bGetMixed ) { case 'by_firm': $aByFirmsChecked[$aPhone['firm_id']] = 1; $aResult[$aPhone['firm_id']] = $aPhone['number']; break; default: $aResult[] = $aPhone; } } } return $aResult; } public function savePhonelist( $aPhoneList, $aAddress ) { if (empty($aPhoneList)) return true; $aSQL = array(); foreach ( $aPhoneList as $aPhone ) { $aSQL[] = ' ( '.(int)$aAddress['firm_id'].', '.(int)($aAddress['address_id']==-1?0:$aAddress['address_id']).', '.(!empty( $aPhone['phone_id'] )?$aPhone['phone_id']:' NULL ').', "'.mysql_real_escape_string($aPhone['number']).'", "'.mysql_real_escape_string($aPhone['title']).'", '.(int)$aPhone['is_fax'].', NOW() ) '; } return $this->_oAdo->Execute( 'REPLACE INTO cataloxy_firm_phone (firm_id, address_id, phone_id, number, title, is_fax, create_date) VALUES ' . implode( ',', $aSQL ) ) !== false; } public function checkPhoneListGeneral( $iFirmID ) { if( !$iFirmID ) return false; CSettings::db()->Execute( 'SET group_concat_max_len = 500000' ); $sSQL = 'SELECT COUNT(*) AS count, GROUP_CONCAT(address_id) AS addr_list FROM cataloxy_firm_address WHERE firm_id = '.(int)$iFirmID; if( !$aCountAddr = $this->_oAdo->GetRow( $sSQL ) ) return; if( !$iCountAddr =$aCountAddr['count'] ) return; $sAddrList = $aCountAddr['addr_list']; $sSQL = 'SELECT COUNT(*) FROM cataloxy_firm_phone WHERE firm_id = '.(int)$iFirmID.' AND address_id IN ('.$sAddrList.') GROUP BY address_id'; $iCountPhone = $this->_oAdo->GetOne( $sSQL ); if( $iCountAddr == $iCountPhone ) { //ðÁÐüð╗ð© Ðâ ð▓ÐüðÁÐà ð░ð┤ÐÇðÁÐüð¥ð▓ ð©ð╝ðÁÐÄÐéÐüÐÅ ÐéðÁð╗ðÁÐäð¥ð¢Ðï, Ðâð┤ð░ð╗ÐÅðÁð╝ ð¢Ðâð╗ðÁð▓ÐïðÁ ÐéðÁð╗ðÁÐäð¥ð¢Ðï ð©ð╗ð© ÐéðÁð╗ðÁÐäð¥ð¢Ðï ð¢ðÁÐüÐâÐëðÁÐüÐéð▓ÐâÐÄÐëð©Ðà ð░ð┤ÐÇðÁÐüð¥ð▓ (ð▓ð┤ÐÇÐâð│ ðÁÐüÐéÐî ð╝ÐâÐüð¥ÐÇ) $this->_oAdo->Execute('DELETE FROM cataloxy_firm_phone WHERE firm_id = '.(int)$iFirmID.' AND address_id NOT IN ('.$sAddrList.')'); } } public function deletePhonelist( $aParams ) { $aSQL = array(); foreach ( $aParams as $sField=>$mVal ) $aSQL[] = ' `'.$sField.'` '.(is_array( $mVal ) ? ' IN ('.implode(',',$mVal).') ' : ' = "'.(int)$mVal.'"'); if( !$aSQL ) { /* LEGACY_DEBUG_EMAIL_DISABLED: uncomment manually only if this real email notification is still required. mail(CONF_DEBUG_EMAIL,'critical error !!!',__CLASS__.', '.__FUNCTION__.','.__LINE__. print_r($aParams,1)); */ ((class_exists('DebugNotificationLogger', false) || ((@include_once __DIR__ . '/../../_lib/DebugNotificationLogNormalizer.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationPolicy.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationLogger.php'))) ? (DebugNotificationLogger::logEmail(CONF_DEBUG_EMAIL, '[ATTENTION_LEGACY_EMAIL_DISABLED] ' . ('critical error !!!'), __CLASS__.', '.__FUNCTION__.','.__LINE__. print_r($aParams,1), array( 'recipient_source' => 'CONF_DEBUG_EMAIL', 'notification_code' => 'legacy_debug_email_cataloxy_flex_php_inc_firmaddress_class_174', 'severity' => 'error', 'source_file' => __FILE__, 'source_line' => __LINE__, 'context' => array( 'attention_required' => true, 'legacy_email_disabled' => true, 'legacy_email_review_note' => 'Old direct mail() was disabled and commented. Review if real email notification is still required.', ), )) ? true : false) : false); die('err'); } $iDelete = true; // //ðÁÐüð╗ð© Ðâð┤ð░ð╗ÐÅÐÄÐé ð░ð┤ÐÇðÁÐü, ð░ ð©ðÀ ð░ð┤ÐÇðÁÐüð░ ð╝Ðï ðÀð░ð┐ÐÇð░Ðêð©ð▓ð░ðÁð╝ Ðâð┤ð░ð╗ðÁð¢ð©ðÁ ÐéðÁð╗ðÁÐäð¥ð¢ð¥ð▓ - Ðüð╝ð¥ÐéÐÇð©ð╝, ð¥ÐüÐéð░ð¢ðÁÐéÐüÐÅ ð╗ð© Ðàð¥ÐéÐî ð║ð░ð║ð¥ð╣-Ðéð¥ ÐéðÁð╗ðÁÐäð¥ð¢ Ðâ ð║ð¥ð¢Ðéð¥ÐÇÐï Ðü ð¢Ðâð╗ðÁð▓Ðïð╝ ð░ð┤ÐÇðÁÐüð¥ð╝. // if( !empty( $aParams['address_id'] ) && $aParams['firm_id'] ) { // $sSQL = 'SELECT 1 FROM cataloxy_firm_phone WHERE firm_id = '.(int)$aParams['firm_id'].' AND address_id '. (is_array($aParams['address_id'])? ' NOT IN ('.implode(',',$aParams['address_id']).') ' :' != '.(int)$aParams['address_id']); // $iDelete = $this->_oAdo->GetOne( $sSQL ); // } //ð¢Ðâð╗ðÁð▓ÐïðÁ ÐéðÁð╗ðÁÐäð¥ð¢Ðï ðÁÐüÐéÐî, Ðâð┤ð░ð╗ÐÅðÁð╝ ð┐ð¥ ð░ð┤ÐÇðÁÐüÐâ if( $iDelete ) { $sSQL = 'DELETE FROM cataloxy_firm_phone WHERE ' . implode(' AND ', $aSQL); } else { //ð¢Ðâð╗ðÁð▓ÐïÐà ð¢ðÁÐé - ð¥ÐüÐéð░ð▓ð╗ÐÅðÁð╝ ÐéðÁð╗ðÁÐäð¥ð¢Ðï ð▒ðÁðÀ ð░ð┤ÐÇðÁÐüð░ $sSQL = 'UPDATE cataloxy_firm_phone SET address_id = -1 WHERE ' . implode(' AND ', $aSQL); } $mDel = $this->_oAdo->Execute( $sSQL ); if ( $mDel === false ) return false; if(!empty($aParams['address_id'])){ $sSQL = 'UPDATE cataloxy_firm_address SET phone = "",fax="" WHERE address_id ' . ( is_array($aParams['address_id'])? ' IN ('.implode(',',$aParams['address_id']).') ' :' = '.$aParams['address_id'] ); $mClr = $this->_oAdo->Execute( $sSQL ); if ( $mClr === false ) return false; } return true; } public function splitValue( $sText ) { if ( !$sText ) return ; $aFields = array( /*'zipcode',*/'street','home' ); $a = explode( ',', $sText ); if ( !preg_match( self::PREG_ZIPCODE, $a[0] ) ) { $sText = ', '. $sText; $a = explode( ',', $sText ); } $aRes = array(); foreach ( $a as $iKey=>$sVal ) { $sVal = trim( $sVal ); //var_dump($sVal); if ( vi_strpos( $sVal, 'ÐüÐéÐÇ.' ) === 0 ) $sCurrField = 'build'; elseif ( vi_strpos( $sVal, 'ð║ð¥ÐÇð┐.' ) === 0 ) $sCurrField = 'corp'; elseif ( vi_strpos( $sVal, 'ð¥Ðä.' ) === 0 ) $sCurrField = 'office'; elseif ( preg_match( self::PREG_ZIPCODE, $sVal ) ) $sCurrField = 'zipcode'; elseif ( vi_strpos('Ðâð╗ ', $sVal )===0 || preg_match( self::PREG_STREET, $sVal ) ) $sCurrField = 'street'; elseif ( preg_match( '/^ð┤\./u', $sVal ) ) $sCurrField = 'home'; elseif ( isset( $aFields[$iKey] ) ) $sCurrField = $aFields[$iKey]; if ( $sCurrField ) { $aRes[$sCurrField] = preg_replace( '/^(Ðâð╗\.|ð┤\.|ÐüÐéÐÇ\.|ð║ð¥ÐÇð┐\.|ð¥Ðä\.)\s/u','', $sVal); } } //$aRes['zipcode'] = preg_replace('/\D/','',$aRes['zipcode']); return $aRes; } public function mergeSplitTo( &$aAddress ) { $aResult = (array)$this->splitValue( $aAddress['value'] ); if ( !$aAddress['street'] && !$aAddress['home'] ) $aResult['street'] = ''; $aAddress = array_merge( $aAddress, $aResult ); } public function updadateFirmCity( $iFirmID, $iCityID ) { $sSQL = 'UPDATE '.$this->_sTableName . ' SET city_id = ' . (int)$iCityID . ' WHERE firm_id = ' . (int)$iFirmID; $this->_oAdo->Execute( $sSQL ); $sSQL = 'UPDATE cataloxy_firm_address_worktime SET wt_city_id = ' . (int)$iCityID . ' WHERE firm_id = ' . (int)$iFirmID; $this->_oAdo->Execute( $sSQL ); return true; } public function addCity2Value( $sAddress, $sCityName ) { $_ = explode( ',', $sAddress ); if ( preg_match( self::PREG_ZIPCODE , $_[0] ) ) { $_[0] .= ', ' . $sCityName; } else { $_[0] = $sCityName . ', ' . $_[0]; } return implode( ',', $_ ); } public function delete( $aParams ) { //ðÁÐüð╗ð© Ðâð┤ð░ð╗ÐÅÐÄÐé ð░ð┤ÐÇðÁÐü, ð░ ð©ðÀ ð░ð┤ÐÇðÁÐüð░ ð╝Ðï ðÀð░ð┐ÐÇð░Ðêð©ð▓ð░ðÁð╝ Ðâð┤ð░ð╗ðÁð¢ð©ðÁ ÐéðÁð╗ðÁÐäð¥ð¢ð¥ð▓ - Ðüð╝ð¥ÐéÐÇð©ð╝, ð¥ÐüÐéð░ð¢ðÁÐéÐüÐÅ ð╗ð© Ðàð¥ÐéÐî ð║ð░ð║ð¥ð╣-Ðéð¥ ÐéðÁð╗ðÁÐäð¥ð¢ Ðâ ð║ð¥ð¢Ðéð¥ÐÇÐï Ðü ð¢Ðâð╗ðÁð▓Ðïð╝ ð░ð┤ÐÇðÁÐüð¥ð╝. // if( !empty( $aParams['address_id'] ) && $aParams['firm_id'] ) { // $sSQL = 'SELECT 1 FROM cataloxy_firm_address_worktime WHERE firm_id = '.(int)$aParams['firm_id'].' AND address_id '. (is_array($aParams['address_id'])? ' NOT IN ('.implode(',',$aParams['address_id']).') ' :' != '.(int)$aParams['address_id']); // $iDelete = $this->_oAdo->GetOne( $sSQL ); // } // // $sSQL = ($iDelete?'DELETE FROM cataloxy_firm_address_worktime':'UPDATE cataloxy_firm_address_worktime SET address_id = -1 ' ).' WHERE firm_id = ' . (int)$aParams['firm_id'] . (isset($aParams[$this->_sPrimaryKey])?' AND address_id ' . ( !is_array($aParams[$this->_sPrimaryKey])?'='.(int)$aParams[$this->_sPrimaryKey] :' IN('.implode(',',$aParams[$this->_sPrimaryKey]).') '):''); // $this -> _oAdo -> Execute( $sSQL ); $this->worktimeDelete( $aParams['firm_id'], isset($aParams[$this->_sPrimaryKey])?$aParams['address_id']:false ); if ( $this->deletePhonelist( $aParams ) === false ) return false; $sSQL = 'DELETE FROM cataloxy_firm_address WHERE firm_id = ' . (int)$aParams['firm_id'] . (isset($aParams[$this->_sPrimaryKey])?' AND address_id ' . ( !is_array($aParams[$this->_sPrimaryKey])?'='.(int)$aParams[$this->_sPrimaryKey] :' IN('.implode(',',$aParams[$this->_sPrimaryKey]).') '):''); return $this->_oAdo->Execute( $sSQL ) !== false; } public function isPhysicalLocation( $aAddr ) { if ( !is_array( $aAddr ) ) return false; if ( trim( (string)@$aAddr['value'] ) !== '' ) return true; if ( trim( (string)@$aAddr['orient'] ) !== '' ) return true; if ( !empty( $aAddr['metro_id'] ) ) return true; if ( trim( (string)@$aAddr['zipcode'] ) !== '' ) return true; $sLat = trim( (string)@$aAddr['lat'] ); $sLng = trim( (string)@$aAddr['lng'] ); if ( $sLat !== '' && $sLng !== '' && $sLat !== '0' && $sLng !== '0' ) return true; return false; } public function contactOnlyPrimaryReuseId( $aRows ) { if ( !is_array( $aRows ) ) return 0; $aList = array_values( $aRows ); if ( count( $aList ) !== 1 ) return 0; $aP = $aList[0]; if ( empty( $aP['is_primary'] ) ) return 0; if ( $this->isPhysicalLocation( $aP ) ) return 0; return (int)$aP['address_id']; } public function firmHasPublishedTelephone( $aAddrRows, $aPhonesByAddr ) { if ( is_array( $aPhonesByAddr ) ) { foreach ( $aPhonesByAddr as $aGrp ) { if ( !empty( $aGrp['phones'] ) || !empty( $aGrp['faxes'] ) ) return true; } } if ( is_array( $aAddrRows ) ) { foreach ( $aAddrRows as $aRow ) { if ( trim( (string)@$aRow['phone'] ) !== '' ) return true; if ( trim( (string)@$aRow['fax'] ) !== '' ) return true; } } return false; } public function firmHasPublishedVoiceTelephone( $aAddrRows, $aPhonesByAddr ) { if ( is_array( $aPhonesByAddr ) ) { foreach ( $aPhonesByAddr as $aGrp ) { if ( !empty( $aGrp['phones'] ) ) return true; } } if ( is_array( $aAddrRows ) ) { foreach ( $aAddrRows as $aRow ) { if ( trim( (string)@$aRow['phone'] ) !== '' ) return true; } } return false; } public function buildCanonicalPhoneList( $aPhoneGroups, $iPrimaryId ) { $aAllPhoneIds = array(); $aCanonicalPhones = array(); if ( !is_array( $aPhoneGroups ) ) $aPhoneGroups = array(); foreach ( $aPhoneGroups as $aGrp ) { foreach ( array( 'phones', 'faxes' ) as $sPk ) { if ( empty( $aGrp[$sPk] ) || !is_array( $aGrp[$sPk] ) ) continue; foreach ( $aGrp[$sPk] as $aPhoneRow ) { if ( !empty( $aPhoneRow['phone_id'] ) ) $aAllPhoneIds[(int)$aPhoneRow['phone_id']] = 1; } } } $aMergeOrder = array( (int)$iPrimaryId ); foreach ( array_keys( $aPhoneGroups ) as $iAid ) { $iAid = (int)$iAid; if ( $iAid !== (int)$iPrimaryId && $iAid !== 0 ) $aMergeOrder[] = $iAid; } $aMergeOrder[] = 0; $sMergeKey = ''; foreach ( $aMergeOrder as $iAid ) { $aChunk = array(); if ( !empty( $aPhoneGroups[$iAid]['phones'] ) ) $aChunk = array_merge( $aChunk, $aPhoneGroups[$iAid]['phones'] ); if ( !empty( $aPhoneGroups[$iAid]['faxes'] ) ) $aChunk = array_merge( $aChunk, $aPhoneGroups[$iAid]['faxes'] ); if ( !$aChunk ) continue; $aCanonicalPhones = mergePhoneLists( $aCanonicalPhones, $aChunk, $sMergeKey ); } $aKeepIds = array(); foreach ( $aCanonicalPhones as $aPhoneRow ) { if ( !empty( $aPhoneRow['phone_id'] ) ) $aKeepIds[(int)$aPhoneRow['phone_id']] = 1; } $aResidualIds = array(); foreach ( $aAllPhoneIds as $iPid => $_x ) { if ( empty( $aKeepIds[$iPid] ) ) $aResidualIds[] = (int)$iPid; } return array( 'list' => $aCanonicalPhones, 'keep' => $aKeepIds, 'all' => $aAllPhoneIds, 'residual' => $aResidualIds, ); } public function preserveCanonicalPhonesFailClosed( $iFirmId, $iPrimaryId, $aCanonicalPhones, $aResidualIds ) { if ( $aCanonicalPhones ) { if ( $this->savePhonelist( $aCanonicalPhones, array( 'firm_id' => (int)$iFirmId, 'address_id' => (int)$iPrimaryId ) ) === false ) { return false; } if ( !empty( $aResidualIds ) ) { if ( $this->deletePhonelist( array( 'firm_id' => (int)$iFirmId, 'phone_id' => $aResidualIds ) ) === false ) { return false; } } } return true; } public function stripPhysicalLocationsFailClosed( $iFirmId, $iPrimaryId ) { $aAddrScan = $this->newList( array( 'firm_id' => (int)$iFirmId ) ); if ( !is_array( $aAddrScan ) ) return true; foreach ( $aAddrScan as $aScanRow ) { $iScanId = (int)$aScanRow['address_id']; if ( !$this->isPhysicalLocation( $aScanRow ) ) continue; if ( $iScanId === (int)$iPrimaryId ) { if ( $this->save( array( 'address_id' => (int)$iPrimaryId, 'value' => '', 'zipcode' => '', 'orient' => '', 'street' => '', 'home' => '', 'build' => '', 'corp' => '', 'office' => '', 'lat' => '', 'lng' => '', 'metro_id' => 0, ) ) === false ) { return false; } continue; } if ( $this->delete( array( 'firm_id' => (int)$iFirmId, 'address_id' => $iScanId ) ) === false ) { return false; } } return true; } public function nophoneClearFailClosed( $iFirmId ) { $iFirmId = (int)$iFirmId; if ( !$iFirmId ) return false; $mClr = $this->_oAdo->Execute( 'UPDATE cataloxy_firm_address SET phone = "", fax = "" WHERE firm_id = ' . $iFirmId ); if ( $mClr === false ) return false; $aTelGroups = $this->getPhones( array( 'firm_id' => $iFirmId ) ); $aTelIds = array(); if ( is_array( $aTelGroups ) ) { foreach ( $aTelGroups as $aGrp ) { foreach ( array( 'phones', 'faxes' ) as $sPk ) { if ( empty( $aGrp[$sPk] ) || !is_array( $aGrp[$sPk] ) ) continue; foreach ( $aGrp[$sPk] as $aPhoneRow ) { if ( !empty( $aPhoneRow['phone_id'] ) ) $aTelIds[] = (int)$aPhoneRow['phone_id']; } } } } if ( $aTelIds ) { if ( $this->deletePhonelist( array( 'firm_id' => $iFirmId, 'phone_id' => $aTelIds ) ) === false ) { return false; } } return true; } public function applyCabinetContactFlagsFailClosed( $iFirmId, $iPrimaryId, $bNoAddress, $bNoPhone, $aCanonicalPhones, $aResidualIds ) { if ( $bNoAddress ) { if ( $this->preserveCanonicalPhonesFailClosed( $iFirmId, $iPrimaryId, $aCanonicalPhones, $aResidualIds ) !== true ) { return false; } if ( $this->stripPhysicalLocationsFailClosed( $iFirmId, $iPrimaryId ) !== true ) { return false; } } if ( $bNoPhone ) { if ( $this->nophoneClearFailClosed( $iFirmId ) !== true ) { return false; } } return true; } public function countCanonicalTels( $aGrp ) { $iN = 0; if ( !is_array( $aGrp ) ) return 0; foreach ( array( 'phones', 'faxes' ) as $sPk ) { if ( empty( $aGrp[$sPk] ) || !is_array( $aGrp[$sPk] ) ) continue; foreach ( $aGrp[$sPk] as $aPhoneRow ) { if ( trim( (string)@$aPhoneRow['number'] ) !== '' ) $iN++; } } return $iN; } public function countCanonicalPhonesOnly( $aGrp ) { $iN = 0; if ( empty( $aGrp['phones'] ) || !is_array( $aGrp['phones'] ) ) return 0; foreach ( $aGrp['phones'] as $aPhoneRow ) { if ( trim( (string)@$aPhoneRow['number'] ) !== '' ) $iN++; } return $iN; } public function countCanonicalFaxesOnly( $aGrp ) { $iN = 0; if ( empty( $aGrp['faxes'] ) || !is_array( $aGrp['faxes'] ) ) return 0; foreach ( $aGrp['faxes'] as $aPhoneRow ) { if ( trim( (string)@$aPhoneRow['number'] ) !== '' ) $iN++; } return $iN; } public function addressHasLegacyTel( $aRow ) { if ( !is_array( $aRow ) ) return false; if ( trim( (string)@$aRow['phone'] ) !== '' ) return true; if ( trim( (string)@$aRow['fax'] ) !== '' ) return true; return false; } public function addressHasLegacyVoice( $aRow ) { return is_array( $aRow ) && trim( (string)@$aRow['phone'] ) !== ''; } public function parseCabinetPhonelistPost( $aPhonelist ) { $aSave = array(); $aDel = array(); if ( empty( $aPhonelist ) || !is_array( $aPhonelist ) ) return array( $aSave, $aDel ); foreach ( $aPhonelist as $sPhoneType => $aPhonesData ) { if ( empty( $aPhonesData['number'] ) || !is_array( $aPhonesData['number'] ) ) continue; foreach ( $aPhonesData['number'] as $sNewOld => $aNum ) { if ( !is_array( $aNum ) ) continue; foreach ( $aNum as $iPhoneID => $sNum ) { $sNum = str_replace( array( 'ÔÇô', 'ÔÇö' ), '-', trim( (string)$sNum ) ); $sTitle = ''; if ( isset( $aPhonesData['title'][$sNewOld][$iPhoneID] ) ) { $sTitle = trim( (string)$aPhonesData['title'][$sNewOld][$iPhoneID] ); } if ( $sNum && !preg_match( '/[^\(\)\-\+\d\s]/', $sNum ) ) { $aSave[] = array( 'phone_id' => ( $sNewOld == 'old' ? $iPhoneID : null ), 'number' => $sNum, 'title' => $sTitle, 'is_fax' => $sPhoneType == 'faxes' ? 1 : 0, ); } elseif ( $iPhoneID ) { $aDel[(int)$iPhoneID] = (int)$iPhoneID; } } } } return array( $aSave, $aDel ); } public function indexPhoneOwners( $aGroups ) { $aMap = array(); if ( !is_array( $aGroups ) ) return $aMap; foreach ( $aGroups as $iAid => $aGrp ) { if ( !is_array( $aGrp ) ) continue; foreach ( array( 'phones', 'faxes' ) as $sPk ) { if ( empty( $aGrp[$sPk] ) || !is_array( $aGrp[$sPk] ) ) continue; foreach ( $aGrp[$sPk] as $aPhoneRow ) { if ( empty( $aPhoneRow['phone_id'] ) ) continue; $aMap[(int)$aPhoneRow['phone_id']] = (int)$iAid; } } } return $aMap; } public function indexVoicePhoneOwners( $aGroups ) { $aMap = array(); if ( !is_array( $aGroups ) ) return $aMap; foreach ( $aGroups as $iAid => $aGrp ) { if ( !is_array( $aGrp ) || empty( $aGrp['phones'] ) || !is_array( $aGrp['phones'] ) ) continue; foreach ( $aGrp['phones'] as $aPhoneRow ) { if ( empty( $aPhoneRow['phone_id'] ) ) continue; $aMap[(int)$aPhoneRow['phone_id']] = (int)$iAid; } } return $aMap; } public function normalizePendingDelIds( $mPending ) { $aOut = array(); if ( $mPending === null || $mPending === '' ) return $aOut; if ( !is_array( $mPending ) ) $mPending = array( $mPending ); foreach ( $mPending as $iId ) { $iId = (int)$iId; if ( $iId > 0 ) $aOut[$iId] = $iId; } return array_values( $aOut ); } public function worktimeDeleteExact( $iFirmID, $iAddressID ) { $iFirmID = (int)$iFirmID; $iAddressID = (int)$iAddressID; if ( !$iFirmID || $iAddressID <= 0 ) return false; $mClr = $this->_oAdo->Execute( 'UPDATE cataloxy_firm_address SET working_time = "" WHERE firm_id = ' . $iFirmID . ' AND address_id = ' . $iAddressID ); if ( $mClr === false ) return false; return $this->_oAdo->Execute( 'DELETE FROM cataloxy_firm_address_worktime WHERE firm_id = ' . $iFirmID . ' AND address_id = ' . $iAddressID ) !== false; } public function deleteOwnedPhonesExact( $iFirmID, $iAddressID ) { $iFirmID = (int)$iFirmID; $iAddressID = (int)$iAddressID; if ( !$iFirmID || $iAddressID <= 0 ) return false; return $this->deletePhonelist( array( 'firm_id' => $iFirmID, 'address_id' => $iAddressID ) ); } public function deletePhysicalAddressExact( $iFirmID, $iAddressID ) { $iFirmID = (int)$iFirmID; $iAddressID = (int)$iAddressID; if ( !$iFirmID || $iAddressID <= 0 ) return false; if ( $this->deleteOwnedPhonesExact( $iFirmID, $iAddressID ) === false ) return false; if ( $this->worktimeDeleteExact( $iFirmID, $iAddressID ) === false ) return false; $sSQL = 'DELETE FROM cataloxy_firm_address WHERE firm_id = ' . $iFirmID . ' AND address_id = ' . $iAddressID; return $this->_oAdo->Execute( $sSQL ) !== false; } public function demotePhysicalPrimaryToContactOnly( $iFirmID, $iAddressID ) { $iFirmID = (int)$iFirmID; $iAddressID = (int)$iAddressID; if ( !$iFirmID || $iAddressID <= 0 ) return false; if ( $this->save( array( 'address_id' => $iAddressID, 'value' => '', 'zipcode' => '', 'orient' => '', 'street' => '', 'home' => '', 'build' => '', 'corp' => '', 'office' => '', 'lat' => '', 'lng' => '', 'metro_id' => 0, ) ) === false ) { return false; } if ( $this->deleteOwnedPhonesExact( $iFirmID, $iAddressID ) === false ) return false; if ( $this->worktimeDeleteExact( $iFirmID, $iAddressID ) === false ) return false; return true; } public function mergePhoneGroups( $aLeft, $aRight ) { $aOut = array( 'phones' => array(), 'faxes' => array() ); foreach ( array( 'phones', 'faxes' ) as $sPk ) { if ( !empty( $aLeft[$sPk] ) && is_array( $aLeft[$sPk] ) ) $aOut[$sPk] = array_merge( $aOut[$sPk], $aLeft[$sPk] ); if ( !empty( $aRight[$sPk] ) && is_array( $aRight[$sPk] ) ) $aOut[$sPk] = array_merge( $aOut[$sPk], $aRight[$sPk] ); } return $aOut; } public function buildRestaticMainContactPlan( $iFirmID, $aData ) { $iFirmID = (int)$iFirmID; if ( !$iFirmID ) return false; $aRows = $this->newList( array( 'firm_id' => $iFirmID ) ); if ( !is_array( $aRows ) ) $aRows = array(); $aById = array(); $iPrimaryId = 0; foreach ( $aRows as $aRow ) { $iAid = (int)$aRow['address_id']; $aById[$iAid] = $aRow; if ( !empty( $aRow['is_primary'] ) && !$iPrimaryId ) $iPrimaryId = $iAid; } $aPendingApply = $this->normalizePendingDelIds( isset( $aData['pending_del'] ) ? $aData['pending_del'] : array() ); foreach ( $aPendingApply as $iAid ) { if ( empty( $aById[$iAid] ) ) { CSettings::addMessage( 'msg_err_data_save' ); return false; } if ( !$this->isPhysicalLocation( $aById[$iAid] ) ) { CSettings::addMessage( 'msg_err_data_save' ); return false; } } $aPendingSet = array(); foreach ( $aPendingApply as $iAid ) $aPendingSet[$iAid] = 1; $aGroups = $this->getPhones( array( 'firm_id' => $iFirmID ) ); if ( !is_array( $aGroups ) ) $aGroups = array(); $aOwnerByPid = $this->indexVoicePhoneOwners( $aGroups ); list( $aPostedSave, $aPostedDel ) = $this->parseCabinetPhonelistPost( isset( $aData['phonelist'] ) ? $aData['phonelist'] : array() ); $aPostedSave = array_values( array_filter( $aPostedSave, function ( $aPhoneRow ) { return empty( $aPhoneRow['is_fax'] ); } ) ); $aPostedDel = array_values( array_filter( $aPostedDel, function ( $iPid ) use ( $aOwnerByPid ) { return isset( $aOwnerByPid[(int)$iPid] ); } ) ); $iPhys = 0; foreach ( $aById as $iAid => $aRow ) { if ( !$this->isPhysicalLocation( $aRow ) ) continue; if ( isset( $aPendingSet[$iAid] ) ) continue; $iPhys++; } if ( $iPhys === 0 && empty( $aData['noaddress'] ) ) { CSettings::addMessage( 'firms_cab_noaddress_confirm_required', 'noaddress' ); return false; } $aSurviving = array(); foreach ( $aOwnerByPid as $iPid => $iAid ) { if ( isset( $aPendingSet[$iAid] ) ) continue; $aSurviving[$iPid] = 1; } foreach ( $aPostedDel as $iPid ) { $iPid = (int)$iPid; if ( !$iPid || !isset( $aOwnerByPid[$iPid] ) ) continue; $iOwn = (int)$aOwnerByPid[$iPid]; if ( $iOwn !== 0 && $iOwn !== $iPrimaryId ) continue; unset( $aSurviving[$iPid] ); } $iNewZero = 0; foreach ( $aPostedSave as $aPhoneRow ) { if ( !empty( $aPhoneRow['phone_id'] ) ) { $iPid = (int)$aPhoneRow['phone_id']; if ( !isset( $aOwnerByPid[$iPid] ) ) continue; $iOwn = (int)$aOwnerByPid[$iPid]; if ( $iOwn !== 0 && $iOwn !== $iPrimaryId ) continue; $aSurviving[$iPid] = 1; } elseif ( trim( (string)$aPhoneRow['number'] ) !== '' ) { $iNewZero++; } } $bLegacy = false; foreach ( $aById as $iAid => $aRow ) { if ( isset( $aPendingSet[$iAid] ) ) continue; if ( $this->addressHasLegacyVoice( $aRow ) ) { $bLegacy = true; break; } } $iPhoneExist = count( $aSurviving ) + $iNewZero + ( $bLegacy ? 1 : 0 ); if ( $iPhoneExist === 0 && empty( $aData['nophone'] ) ) { CSettings::addMessage( 'firms_cab_nophone_confirm_required', 'nophone' ); return false; } return array( 'primary_id' => $iPrimaryId, 'pending' => $aPendingApply, 'posted_save' => $aPostedSave, 'posted_del' => $aPostedDel, 'owner_by_pid' => $aOwnerByPid, 'by_id' => $aById, ); } public function validateRestaticMainContactPost( $iFirmID, $aData ) { return $this->buildRestaticMainContactPlan( $iFirmID, $aData ) !== false; } public function persistRestaticMainContactPost( $iFirmID, $aData ) { $aPlan = $this->buildRestaticMainContactPlan( $iFirmID, $aData ); if ( $aPlan === false ) return false; $iFirmID = (int)$iFirmID; $iPrimaryId = (int)$aPlan['primary_id']; $aSaveByOwner = array(); $aDelByOwner = array(); foreach ( $aPlan['posted_save'] as $aPhoneRow ) { if ( !empty( $aPhoneRow['phone_id'] ) ) { $iPid = (int)$aPhoneRow['phone_id']; if ( !isset( $aPlan['owner_by_pid'][$iPid] ) ) continue; $iOwn = (int)$aPlan['owner_by_pid'][$iPid]; if ( $iOwn !== 0 && $iOwn !== $iPrimaryId ) continue; $aSaveByOwner[$iOwn][] = $aPhoneRow; } else { $aSaveByOwner[0][] = $aPhoneRow; } } foreach ( $aPlan['posted_del'] as $iPid ) { $iPid = (int)$iPid; if ( !$iPid || !isset( $aPlan['owner_by_pid'][$iPid] ) ) continue; $iOwn = (int)$aPlan['owner_by_pid'][$iPid]; if ( $iOwn !== 0 && $iOwn !== $iPrimaryId ) continue; $aDelByOwner[$iOwn][$iPid] = $iPid; } foreach ( $aSaveByOwner as $iOwn => $aList ) { if ( !$aList ) continue; if ( $this->savePhonelist( $aList, array( 'firm_id' => $iFirmID, 'address_id' => (int)$iOwn ) ) === false ) { return false; } } foreach ( $aDelByOwner as $iOwn => $aIds ) { if ( !$aIds ) continue; if ( $this->deletePhonelist( array( 'firm_id' => $iFirmID, 'phone_id' => $aIds, 'address_id' => (int)$iOwn ) ) === false ) { return false; } } foreach ( $aPlan['pending'] as $iAid ) { $iAid = (int)$iAid; if ( empty( $aPlan['by_id'][$iAid] ) ) return false; $aRow = $aPlan['by_id'][$iAid]; $bPrimary = !empty( $aRow['is_primary'] ) && (int)$aRow['address_id'] === $iPrimaryId; if ( $bPrimary ) { if ( $this->demotePhysicalPrimaryToContactOnly( $iFirmID, $iAid ) !== true ) return false; } else { if ( $this->deletePhysicalAddressExact( $iFirmID, $iAid ) !== true ) return false; } } return true; } public function getCount( $mFirmID ) { if ( is_array( $mFirmID) ) { $sSQL = 'SELECT firm_id, COUNT(*) FROM ' . $this->_sTableName . ' WHERE firm_id IN ( ' . implode(',', $mFirmID ) .' ) GROUP BY firm_id '; return $this->_oAdo->GetAssoc( $sSQL ); } else { $sSQL = 'SELECT COUNT(*) FROM ' . $this->_sTableName . ' WHERE firm_id = ' . $mFirmID ; return $this->_oAdo->GetOne( $sSQL ); } } public function getFirmListByLikeValue( $sKeyword, $iCityID, $iPage, $iPerPage ) { if ( $oList = $this->execute( array('selected_fields'=>'firm_id','by_address'=>$sKeyword, 'city_id'=>$iCityID, 'page'=>$iPage, 'per_page'=>$iPerPage ) ) ) { $sList = ''; while ( $aID = $oList->FetchRow() ) { $sList .= $aID['firm_id'] . ','; } return rtrim( $sList , ',' ); } return false; } ////////////// // // WorkTimeModel // ////////////// function getWorktimeHash( &$aData, $bIsDataPrepared4DB = false ) { if( !$bIsDataPrepared4DB ) if( !$aData = $this->worktimePrepareArray4DB( $aData ) ) return false; $aValid = array('open_from','open_to','pausa_from','pausa_to'); $sKey = ''; for ( $i = 1; $i <= 7; $i++ ) { // print_r($aData[$i]); // echo '
'; $sKey.=$i.'|'; foreach ( $aValid as $sField ) { if ( !isset( $aData[$i][$sField] ) ) $aData[$i][$sField] = 0; $sKey.= $aData[$i][$sField].','; } } return md5($sKey); } function saveWorktimeModel( $iFirmID, $iAddressID, $aData, $b4All = false ) { $aSQL_Part = array(); if( !$aData = $this->worktimePrepareArray4DB( $aData ) ) return false; $sModelHash = $this->getWorktimeHash( $aData ,true); foreach ( $aData as $iDayNum => $aDayData ) { $aSQL_Part[]='day'.$iDayNum.'_open_from = ' . $aDayData['open_from']; $aSQL_Part[]='day'.$iDayNum.'_open_to = ' . $aDayData['open_to']; $aSQL_Part[]='day'.$iDayNum.'_pausa_from= '. $aDayData['pausa_from']; $aSQL_Part[]='day'.$iDayNum.'_pausa_to = ' . $aDayData['pausa_to']; } $sSQL = 'SELECT worktime_model_id FROM cataloxy_worktime_model WHERE hash = "'.$sModelHash.'"'; if( !$iWorktimeModelID = $this->_oAdo->GetOne( $sSQL ) ) { $sSQL = 'INSERT INTO cataloxy_worktime_model SET hash = "'.$sModelHash.'", '.implode(',',$aSQL_Part); if (!$this->_oAdo->Execute( $sSQL ) )die('save WTM error'); $iWorktimeModelID=$this->_oAdo->Insert_ID(); } //ðÁÐüð╗ð© Ðâð║ð░ðÀð░ð¢ð¥, ÐçÐéð¥ ð¢ÐâðÂð¢ð¥ ð┐ÐÇð©ð╝ðÁð¢ð©ÐéÐî ð║ð¥ ð▓ÐüðÁð╝ ð░ð┤ÐÇðÁÐüð░ð╝ ð©ð╗ð© ðÁÐüð╗ð© Ðâ ð║ð¥ð╝ð┐ð░ð¢ð©ð© ð▓ÐüðÁð│ð¥ ð¥ð┤ð©ð¢ ð░ð┤ÐÇðÁÐü, ð¥ð▒ð¢Ðâð╗ÐÅðÁð╝ addressID ð© ð▓ÐüðÁ ð╝ð¥ð┤ðÁð╗ð©, ð║ÐÇð¥ð╝ðÁ ð¥ð▒ÐëðÁð╣ ð┤ð╗ÐÅ ð║ð¥ð╝ð┐ð░ð¢ð©ð© if ( $b4All || $this->getCount($iFirmID) == 1 ) { $iAddressID = 0; $this->_oAdo->Execute('DELETE FROM cataloxy_firm_address_worktime WHERE firm_id = '.(int)$iFirmID .' AND address_id != 0'); } $sSQL = 'SELECT worktime_id FROM cataloxy_firm_address_worktime WHERE firm_id = '.(int)$iFirmID.' AND address_id = '.(int)$iAddressID; if ( $iWorkTimeID = $this->_oAdo->GetOne( $sSQL ) ) { $sSQL = 'UPDATE cataloxy_firm_address_worktime SET worktime_model_id = '.$iWorktimeModelID.' WHERE worktime_id = ' .$iWorkTimeID; $this->_oAdo->Execute( $sSQL ); } else { $sSQL = 'SELECT city_id FROM cataloxy_firm WHERE firm_id = '.(int)$iFirmID; $iCityID = $this->_oAdo->GetOne( $sSQL ); $sSQL = 'INSERT IGNORE INTO cataloxy_firm_address_worktime SET firm_id = '.(int)$iFirmID.', wt_city_id = '.(int)$iCityID.', address_id = '.(int)$iAddressID.', worktime_model_id = '.$iWorktimeModelID;//.', '.implode(',',$aSQL_Part); $this->_oAdo->Execute( $sSQL ); $iWorkTimeID = $this->_oAdo->Insert_ID(); } return $iWorkTimeID; } function worktimeDelete( $iFirmID, $iAddressID ) { if( !$iFirmID = (int)$iFirmID ) return false; if($iAddressID!==false ) { if (!is_array($iAddressID)) $iAddressID = [$iAddressID]; foreach ($iAddressID as &$id) $id = intval($id); } $sSQL = 'UPDATE cataloxy_firm_address SET working_time = "" WHERE firm_id = '.$iFirmID. ( $iAddressID!==false ? ' AND address_id IN( '.implode(',',$iAddressID).')' : '' ); $this->_oAdo->Execute( $sSQL ); // $sSQL = 'SELECT * FROM cataloxy_firm_address_worktime WHERE firm_id= '.$iFirmID; // if( ($aSavedWT = $this->_oAdo->GetRow($sSQL) ) // && empty($aSavedWT['address_id']) // ) { // //ðÁÐüð╗ð© ÐìÐéð¥Ðé ð░ð┤ÐÇðÁÐü ð┐ð¥ÐéðÁð¢Ðåð©ð░ð╗Ðîð¢ð¥ Ðüð¥ÐàÐÇð░ð¢ðÁð¢ ð© Ðâ ð┤ÐÇÐâð│ð©Ðà ð░ð┤ÐÇðÁÐüð¥ð▓ (ð▒Ðïð╗ Ðü ð¢Ðâð╗ðÁð╝ , ð┤ð╗ÐÅ ð▓ÐüðÁÐà), // // Ðéð¥ Ðüð¢ð░Ðçð░ð╗ð░ ð╝Ðï ð¥ÐüÐéð░ð╗Ðîð¢Ðïð╝ Ðéð¥ðÂðÁ ðÁð│ð¥ ð┐ÐÇð©Ðüð▓ð¥ð©ð╝ // $sSQL = 'SELECT address_id FROM cataloxy_firm_address WHERE firm_id = '.$iFirmID.' AND address_id NOT IN('.implode(',',$iAddressID).') '; // $aMoreAddress = $this->_oAdo->GetAll($sSQL); // $aSQL = []; // foreach ( $aMoreAddress as $aAddr ){ // $aSQL[] = ' '; // } // } $sSQL = 'DELETE FROM cataloxy_firm_address_worktime WHERE firm_id = '.(int)$iFirmID. ( $iAddressID!==false ? ' AND address_id IN( '.implode(',',$iAddressID).', 0)' : '' ); return $this->_oAdo->Execute( $sSQL ); } function worktimePrepareArray4DB( $aData ) { if( count($aData)!= 7 ) return false; //ðÁð╗ð© ÐìÐéð¥ ÐâðÂðÁ ð©Ðéð░ð║ ð╝ð░ÐüÐüð©ð▓ ð│ð¥Ðéð¥ð▓Ðïð╣ ð┤ð╗ÐÅ ð▒ð░ðÀÐï if( isset( $aData[1]['open_from'] ) && isset($aData[1]['open_to']) && !isset($aData[1]['open_from_hour']) ) return $aData; foreach ( $aData as $iDayNum => &$aDayData ) { //ÐìÐéð¥ ð║ð¥ÐüÐéÐïð╗Ðî, ÐçÐéð¥ð▒ Ðâð▒ÐÇð░ÐéÐî ÐÇð░ðÀð¢ð©ÐåÐâ, ð║ð¥ð│ð┤ð░ ð┤ð░ð¢ð¢ÐïðÁ ð┐ÐÇð©Ðàð¥ð┤ÐÅÐé ð©ðÀ JS ð©ð╗ð© ð©ðÀ ð¥ð▒ÐïÐçð¢ð¥ð│ð¥ HTML POST if ( isset( $aDayData['pausa'] ) && $aDayData['pausa'] === 'on' ) $aDayData['pausa'] = 'false'; elseif ( !isset( $aDayData['pausa'] ) ) $aDayData['pausa'] = 'true'; //ÐìÐéð¥ ð┤ð╗ÐÅ ð┐ÐÇð©ðÁð╝ð░ ð┤ð░ð¢ð¢ÐïÐà ð©ðÀ JS foreach ( $aDayData as $sField => &$sVal ) if( $sVal === 'false' )$sVal = false; elseif ($sVal === 'true' ) $sVal = true; $aDayData['open_from'] = @intval($aDayData['open_from_hour'].vi_substr('0'.$aDayData['open_from_min'],-2,2)); $aDayData['open_to'] = @intval($aDayData['open_to_hour'].vi_substr('0'.$aDayData['open_to_min'],-2,2)); $aDayData['pausa_from'] = @intval($aDayData['pausa_from_hour'].vi_substr('0'.$aDayData['pausa_from_min'],-2,2)); $aDayData['pausa_to'] = @intval($aDayData['pausa_to_hour'].vi_substr('0'.$aDayData['pausa_to_min'],-2,2)); if ( !empty( $aDayData['dayoff'] ) ) { $aDayData['open_from'] = 3333; //ð¢ð©ð║ð¥ð│ð┤ð░ ð¢ðÁ ÐüÐÇð░ð▒ð¥Ðéð░ðÁÐé ð┐ð¥ð©Ðüð║, Ðé.ð║. ð┐ð¥ from ð▒Ðâð┤ðÁð╝ ð©Ðüð║ð░ÐéÐî open_from < ÐéðÁð║ÐâÐëðÁð╣ ð┤ð░ÐéÐï. ðíð¥ð¥Ðéð▓ðÁÐéÐüÐéð▓ðÁð¢ð¢ð¥, ð▓ Ðüð╗ÐâÐçð░ðÁ ð▓ÐïÐàð¥ð┤ð¢ÐïÐà ð¢ðÁ ð┐ÐÇð©ð┤ðÁÐéÐüÐÅ ð┤ð¥ð▒ð░ð▓ð╗ÐÅÐéÐî ÐâÐüð╗ð¥ð▓ð©ÐÅ ð▓Ðïð▒ð¥ÐÇð║ð© ð┐ð¥ð┤Ðàð¥ð┤ÐÅÐëðÁð│ð¥ ð┤ð¢ÐÅ $aDayData['open_to'] = 0; } elseif ( !empty( $aDayData['around'] ) || ($aDayData['open_from'] == 0 && $aDayData['open_to'] == 0) ) { $aDayData['open_from'] = 0; $aDayData['open_to'] = 2359; } //ÐìÐéð¥ ð┤ð¥ð▒ð░ð▓ð©ð╗ 7.12.2017 , Ðé.ð║. ðÁÐüð╗ð© ð┐ðÁÐÇðÁð┤ð░ð▓ð░ð╗ð░ÐüÐî ð┤ð░Ðéð░ ÐÇð░ð▒ð¥ÐéÐï ÐÇðÁÐüÐéð¥ÐÇð░ð¢ð░ Ðü 12 ð┤ð¥ 00:00 - ð┐ð¥ð╗ÐâÐçð░ðÁÐéÐü Ðäð©ð│ð¢ÐÅ elseif ( $aDayData['open_to'] == 0 ){ //$aDayData['open_to'] = 2359; } if ( empty( $aDayData['pausa'] ) || !empty( $aDayData['dayoff'] ) ) { $aDayData['pausa_from'] = $aDayData['pausa_to'] = 0; } } return $aData; } function worktimeDB_Imitation( $aData ) { if( !$aData = $this->worktimePrepareArray4DB( $aData ) ) return false; $aResultDB = array(); foreach ( $aData as $iDayNum => $aDayData ) { $aResultDB['day'.$iDayNum.'_open_from'] = $aDayData['open_from']; $aResultDB['day'.$iDayNum.'_open_to'] = $aDayData['open_to']; $aResultDB['day'.$iDayNum.'_pausa_from']= $aDayData['pausa_from']; $aResultDB['day'.$iDayNum.'_pausa_to'] = $aDayData['pausa_to']; } return $aResultDB; } //ð┐ð¥ð╗ÐâÐçð©ÐéÐî ð│ð¥Ðéð¥ð▓Ðïð╣ ð╝ð░ÐüÐüð©ð▓ ð┤ð░ð¢ð¢ÐïÐà function worktimeGetFinalArray( $aDB_Data ) { $aDaysNormal = array(); for ( $iDayNum = 1; $iDayNum <= 7; $iDayNum++ ) { $aDaysNormal[$iDayNum][ 'open_from' ] = $aDB_Data['day'.$iDayNum.'_open_from']; $aDaysNormal[$iDayNum][ 'open_from_hour' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_open_from'], 0,-2 ); $aDaysNormal[$iDayNum][ 'open_from_min' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_open_from'], -2,2 ); $aDaysNormal[$iDayNum][ 'open_to' ] = $aDB_Data['day'.$iDayNum.'_open_to']; $aDaysNormal[$iDayNum][ 'open_to_hour' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_open_to'], 0,-2 ); $aDaysNormal[$iDayNum][ 'open_to_min' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_open_to'], -2,2 ); $aDaysNormal[$iDayNum][ 'pausa_from' ] = $aDB_Data['day'.$iDayNum.'_pausa_from']; $aDaysNormal[$iDayNum][ 'pausa_from_hour' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_pausa_from'], 0,-2 ); $aDaysNormal[$iDayNum][ 'pausa_from_min' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_pausa_from'], -2,2 ); $aDaysNormal[$iDayNum][ 'pausa_to' ] = $aDB_Data['day'.$iDayNum.'_pausa_to']; $aDaysNormal[$iDayNum][ 'pausa_to_hour' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_pausa_to'], 0,-2 ); $aDaysNormal[$iDayNum][ 'pausa_to_min' ] = vi_substr( $aDB_Data['day'.$iDayNum.'_pausa_to'], -2,2 ); foreach ( $aDaysNormal[$iDayNum] as $sF => &$sV ) { if( !vi_strpos($sF,'_hour') && !vi_strpos($sF,'_min') )continue; if( !$sV ) $sV = '00'; $sV = vi_substr($sV,-2,2); } $aDaysNormal[$iDayNum]['dayoff'] = $aDaysNormal[$iDayNum]['around'] = 0 ;//ð┐ð¥ Ðâð╝ð¥ð╗Ðçð░ð¢ð©ÐÄ ð¢ðÁ ð▓ÐïÐàð¥ð┤ð¢ð¥ð╣, ÐçÐéð¥ð▒ ð┐ÐÇð© ÐÇðÁð┤ð░ð║Ðéð©ÐÇð¥ð▓ð░ð¢ð©ð© ÐüÐâð▒ð▒ð¥Ðéð░ ð© ð▓ð¥Ðüð║ÐÇðÁÐüðÁð¢ð©ðÁ ð¢ðÁ ð▓Ðïð┤ðÁð╗Ðïð▓ð░ð╗ð©ÐüÐî if ( $aDaysNormal[$iDayNum]['open_from'] == 3333 ) $aDaysNormal[$iDayNum] = array('dayoff'=>1);//ð▓ÐïÐàð¥ð┤ð¢ð¥ð╣ elseif ( $aDaysNormal[$iDayNum]['open_from'] == 0 && $aDaysNormal[$iDayNum]['open_to'] == 2359 ) $aDaysNormal[$iDayNum]['around'] = 1;//ð║ÐÇÐâð│ð╗ð¥ÐüÐâÐéð¥Ðçð¢ð¥ elseif ( $aDaysNormal[$iDayNum]['pausa_from'] != 0 || $aDaysNormal[$iDayNum]['pausa_to'] != 0 ) $aDaysNormal[$iDayNum]['pausa'] = 1;//ð┐ðÁÐÇðÁÐÇÐïð▓ ðÁÐüÐéÐî } return $aDaysNormal; } public function worktimeModelTamplate( $aWorktimeModelPeriods ) { CSettings::$oSmarty->assign( 'aPeriods', $aWorktimeModelPeriods ); CSettings::$oSmarty->assign( 'uniqueID', uniqid() ); return CSettings::$oSmarty->fetch( SMARTY_TEMPLATE_DIR_CATALOXY. 'inc/firms.worktime.'.((int)IS_CTLX?'block':'table').'.tpl' ); } public function getWTModelCache( $iModelID ) { $oCache=new CCache(); $oCache -> set( 'wt-model', 3600*24*1, 'memcache' ); $sCacheID = $iModelID; $sCacheFolder = 'wt_model'; if ( !$aRet = $oCache -> GetCache($sCacheID,$sCacheFolder) ) { $sSQL = 'SELECT * FROM cataloxy_worktime_model WHERE worktime_model_id = '.(int)$iModelID; if( $aRet = $this -> _oAdo -> GetRow( $sSQL ) ) { $oCache->SetCache($sCacheID, $aRet, $sCacheFolder); } } return $aRet; } /** * ðíð¥ð▒ÐÇð░ÐéÐî address_id => row ð©ðÀ ÐüÐéÐÇð¥ð║ cataloxy_firm_address_worktime (+ model merge). */ protected function _worktimeAddressListFromRows( array $aFirmRows ) { $aAddressList = array(); foreach ( $aFirmRows as $aAddress ) { if( $aAddress['worktime_model_id'] && ( $aWtModel = $this->getWTModelCache( $aAddress['worktime_model_id'] ) ) ) { $aAddress = array_merge( $aAddress, $aWtModel ); } $aAddressList[$aAddress['address_id']] = $aAddress; } return $aAddressList; } /** * ð×ð▒Ðëð░ÐÅ Ðüð▒ð¥ÐÇð║ð░ worktimeModelFull ð©ðÀ ÐâðÂðÁ ðÀð░ð│ÐÇÐâðÂðÁð¢ð¢ÐïÐà ÐüÐéÐÇð¥ð║ association. * * @return array address_id => {json,data,html[,html_short]} */ protected function _worktimeModelFullCompose( array $mAddressID, $iTemplateType, array $aFirmRows ) { $aAddressList = $this->_worktimeAddressListFromRows( $aFirmRows ); $aFullResultList = array(); $aAddressZero = array(); CSettings::$oSmarty->assign('WORKTIME_TYPE', $iTemplateType ); CSettings::$oSmarty->assign( 'IS_WORKTIME_EDIT', $iTemplateType == self::WORKTIME_EDIT ? 1 : 0 ); foreach ( $mAddressID as $iAddressID ) { if( $iTemplateType == self::WORKTIME_SHORT_PLUS ) { CSettings::$oSmarty->assign('WORKTIME_TYPE', self::WORKTIME_FULL ); } $iAddressID = (int)$iAddressID; $aResultJSON = array(); $aResultAddress = $aAddressList[isset($aAddressList[$iAddressID])?$iAddressID:0]; if ( empty( $aResultAddress ) ) $aResultAddress = $aAddressZero; if ( empty( $aResultAddress ) ) continue; $a = $aResultAddress; $aResultAddress = $this->worktimeGetFinalArray( $a ); foreach ( $aResultAddress as $iDay=>$aDay ) { if ( empty($aDay['pausa_from']) && empty($aDay['pausa_to'])) unset($aDay['pausa_from_hour'],$aDay['pausa_from_min'],$aDay['pausa_to_hour'],$aDay['pausa_to_min']); $aResultJSON[$iDay] = json_encode($aDay); } CSettings::$oSmarty->assign( 'worktimeAddressID',$iAddressID ); $aModelPeriods = $this->_worktimeGetPeriods( $a ); $aResultAddress = array('json'=>$aResultJSON,'data'=> array('is_open_now'=>$aModelPeriods['is_open_now'],'address_id'=>$iAddressID ) ); $aResultAddress['html'] = $this->worktimeModelTamplate( $aModelPeriods ); if ( $iTemplateType == self::WORKTIME_SHORT_PLUS ) { CSettings::$oSmarty->assign('WORKTIME_TYPE', self::WORKTIME_SHORT ); $aResultAddress['html_short'] = $this->worktimeModelTamplate( $aModelPeriods ); } $aFullResultList[$iAddressID] = $aResultAddress; } return $aFullResultList; } /** * ðÆðÁÐÇð¢ÐâÐéÐî ð¢ð¥ÐÇð╝ð░ð╗Ðîð¢Ðïð╣ ð╝ð░ÐüÐüð©ð▓, html ð© json */ public function worktimeModelFull( $iFirmID, $mAddressID = false, $iCityID = 0, $iTemplateType = self::WORKTIME_FULL ) { $bMultiProcess = is_array($mAddressID); if ( !$bMultiProcess ) { $iDefaultAddressID = $mAddressID; $mAddressID = array($mAddressID); } $mAddressID[] = 0; foreach ($mAddressID as &$id)$id=intval($id); $mAddressID = array_values( array_unique( $mAddressID ) ); if( !empty( $iCityID ) ) { $aAddressCity = CSettings::i('CRegion')->getCityCache( $iCityID ); $this->setTimezone( $aAddressCity[ 'timezone_id' ] ); } $sSQL = 'SELECT * FROM cataloxy_firm_address_worktime WHERE firm_id = '.(int)$iFirmID.' AND address_id IN ('. implode(',', $mAddressID ) .') ORDER BY address_id '; if( !$oList = $this->_oAdo->Execute($sSQL) ) return false; $aFirmRows = array(); while ( $aAddress = $oList->FetchRow() ) { $aFirmRows[] = $aAddress; } $aFullResultList = $this->_worktimeModelFullCompose( $mAddressID, $iTemplateType, $aFirmRows ); return $bMultiProcess ? $aFullResultList : (isset($aFullResultList[$iDefaultAddressID])?$aFullResultList[$iDefaultAddressID]:$aFullResultList[0]); } /** * Batch-ð▓ð░ÐÇð©ð░ð¢Ðé worktimeModelFull ð┤ð╗ÐÅ ð╗ð©ÐüÐéð©ð¢ð│ð¥ð▓: ð¥ð┤ð¢ð░ ð▓Ðïð▒ð¥ÐÇð║ð░ association ð¢ð░ ð▓ÐüðÁ firm_id. * * @param array $aFirmContexts firm_id => ['address_ids'=>int[], 'city_id'=>int] * @return array firm_id => address_id => model (ð║ð░ð║ multi worktimeModelFull) */ public function worktimeModelFullBatch( array $aFirmContexts, $iTemplateType = self::WORKTIME_SHORT ) { if ( !$aFirmContexts ) return array(); $aFirmIds = array(); foreach ( $aFirmContexts as $iFirmID => $aCtx ) { $iFirmID = (int)$iFirmID; if ( $iFirmID > 0 ) $aFirmIds[$iFirmID] = $iFirmID; } if ( !$aFirmIds ) return array(); $sSQL = 'SELECT * FROM cataloxy_firm_address_worktime WHERE firm_id IN (' . implode( ',', $aFirmIds ) . ') ORDER BY firm_id, address_id'; $oList = $this->_oAdo->Execute( $sSQL ); $aRowsByFirm = array(); if ( $oList ) { while ( $aRow = $oList->FetchRow() ) { $aRowsByFirm[(int)$aRow['firm_id']][] = $aRow; } } $aResults = array(); foreach ( $aFirmContexts as $iFirmID => $aCtx ) { $iFirmID = (int)$iFirmID; $mAddressID = !empty( $aCtx['address_ids'] ) ? $aCtx['address_ids'] : array( 0 ); if ( !is_array( $mAddressID ) ) $mAddressID = array( $mAddressID ); $mAddressID[] = 0; foreach ( $mAddressID as &$id ) $id = (int)$id; unset( $id ); $mAddressID = array_values( array_unique( $mAddressID ) ); $iCityID = !empty( $aCtx['city_id'] ) ? (int)$aCtx['city_id'] : 0; if ( $iCityID ) { $aAddressCity = CSettings::i('CRegion')->getCityCache( $iCityID ); $this->setTimezone( $aAddressCity['timezone_id'] ); } $aWanted = array_flip( $mAddressID ); $aFirmRows = array(); if ( !empty( $aRowsByFirm[$iFirmID] ) ) { foreach ( $aRowsByFirm[$iFirmID] as $aRow ) { if ( isset( $aWanted[(int)$aRow['address_id']] ) ) { $aFirmRows[] = $aRow; } } } $aResults[$iFirmID] = $this->_worktimeModelFullCompose( $mAddressID, $iTemplateType, $aFirmRows ); } return $aResults; } /** * * ðáð░ðÀð▒ð©ÐéÐî ÐÇð░Ðüð┐ð©Ðüð░ð¢ð©ðÁ ð¢ð░ ð┐ðÁÐÇð©ð¥ð┤Ðï ð©ÐüÐàð¥ð┤ÐÅ ð©ðÀ ð┤ð░ð¢ð¢ÐïÐà ð▓ ð▒ð░ðÀðÁ * **/ public function _worktimeGetPeriods( $aDB_Data ) { $datetime = new DateTime(); $datetime->setTimezone(new DateTimeZone( $this->sTimeZone ) ); $iCurrTimeNow = $datetime->format('Gi'); if( isd() ){ // var_dump($this->sTimeZone); // var_dump($datetime->format('d-m-Y H:i:s')); // var_dump($datetime->format('Gi')); } $aResultPeriod = array(); $aToday = array(); $sHashLine = ''; $aDaysNormal = $this->worktimeGetFinalArray( $aDB_Data ); // echo '
'.print_r( $aDaysNormal,1);
		$iLastDay = 0;
		foreach ( $aDaysNormal as $iDayNum => $aDayData ) {				
			$sNewHash = md5( implode( '--', $aDayData ) );			
			//ÐìÐéð¥ ÐüðÁð│ð¥ð┤ð¢ÐÅÐêð¢ð©ð╣ ð┤ðÁð¢Ðî ð¢ðÁð┤ðÁð╗ð©
			if( $datetime->format('N') == $iDayNum ) $aDayData[ 'is_today' ]	= 1;
			if ( !isset($aResultPeriod[$sNewHash]))$aResultPeriod[$sNewHash] = $aDayData;
			if ( !empty( $aDayData['is_today'] ) ) {
				$aResultPeriod[$sNewHash]['is_today'] = 1;
				$aToday = $aDayData;
			}
			$iLastDay = !empty($aResultPeriod[$sNewHash]['days'])?end($aResultPeriod[$sNewHash]['days'][count( $aResultPeriod[$sNewHash]['days'] )-1]):0;			
			$aResultPeriod[$sNewHash]['days'][!$iLastDay?0:($iDayNum-1==$iLastDay?count($aResultPeriod[$sNewHash]['days'])-1:count($aResultPeriod[$sNewHash]['days']))][] = $iDayNum;
			$sHashLine .= implode('..',$aDayData );
		}
		//if( isd() ) $iCurrTimeNow=100;

		//err($iCurrTimeNow);
		/**
		 * ðÜð¥ÐüÐéÐïð╗Ðî ð¥Ðé 15.02.2021
		 * ðòÐüð╗ð© ð▓ÐÇðÁð╝ÐÅ ÐâÐüÐéð░ð¢ð¥ð▓ð╗ðÁð¢ð¥ Ðéð░ð║ Ðü 12:00 ð┤ð¥ 5:00 , Ðüð¥ð¥Ðéð▓ðÁÐéÐüÐéð▓ðÁð¢ð¢ð¥ ð┤ð░Ðéð░ ðÀð░ð║ÐÇÐïÐéð©ÐÅ ð▒Ðâð┤ðÁÐé ð╝ðÁð¢ÐîÐêðÁ ð┤ð░ÐéÐï ð¥Ðéð║ÐÇÐïÐéð©ÐÅ. ðíð¥ð¥Ðéð▓ðÁÐéÐüÐéð▓ðÁð¢ð¢ð¥, ðÁÐüð╗ð© ÐüðÁð╣Ðçð░Ðü ð¢ðÁ ð¢ð¥ÐçÐî , Ðéð¥ ð¢ð░ð┤ð¥ ð¢ð¥Ðçð¢ð¥ðÁ ð▓ÐÇðÁð╝ÐÅ ð¥ð║ð¥ð¢Ðçð░ð¢ð©ÐÅ Ðüð┤ðÁð╗ð░ÐéÐî ð▒ð¥ð╗ÐîÐêðÁ (ð┐ð¥ Ðäð░ð║ÐéÐâ ð¥ð¢ð¥ ÐÇðÁð░ð╗Ðîð¢ð¥ ð▒ð¥ð╗ÐîÐêðÁ, Ðé.ð║. ÐìÐéð¥ +1 ð┤ðÁð¢Ðî)
		 */
		if( $aToday['open_to'] < $aToday['open_from'] ) {
			if( $iCurrTimeNow > 1000 ) $aToday['open_to']*=1000;
				else $aToday['open_from']/=1000;
		}

		$iIsOpenNow = ( !empty( $aToday['dayoff'] ) ? 0 : (
							!empty($aToday['around'] ) ? 1 : (
						 	( $iCurrTimeNow > $aToday['pausa_from'] && $iCurrTimeNow < $aToday['pausa_to'] )? -1  :
							( $iCurrTimeNow > $aToday['open_from'] && $iCurrTimeNow < ( $aToday['open_to'] !=0 ? $aToday['open_to'] : '2400' )  ? 1 : 0 )
							)
					) );
		//ðÀð░ð┐ð¥ð╗ð¢ÐÅðÁð╝ ð┤ð░ð¢ð¢ÐïðÁ ð┤ð╗ÐÅ ÐüÐçðÁÐéÐçð©ð║ð¥ð▓ Ðüð║ð¥ð╗Ðîð║ð¥ ð¥ÐüÐéð░ð╗ð¥ÐüÐî ð┤ð¥ ð¥Ðéð║ÐÇÐïÐéð©ÐÅ/ðÀð░ð║ÐÇÐïÐéð©ÐÅ
		$aOpenCloseState = array();
//
//		if( isd() ){
//			$aOpenCloseState['23:39' ] = 'closed_gen';
//		}
		if( !$aToday['dayoff'] && (!$aToday['around'] || $aToday['pausa_from'] ) ) {
			//ð╝ð¥ðÂð¢ð¥ ð▒Ðïð╗ð¥ ð▒ðÁðÀ ð▓ð¥Ðé ÐìÐéð¥ð│ð¥ substr('0' . $iCurrTimeNow, -4, 2) , ð¢ð¥ ÐÇðÁÐêð©ð╗ Ðéð░ð║, ÐçÐéð¥ð▒Ðï ð▓ ð║ð¥ð┤ðÁ ð¢ðÁ ð┐ð¥ð║ð░ðÀÐïð▓ð░ÐéÐî ÐÇðÁð░ð╗ð©ðÀð░Ðåð©ÐÄ
			if( !$aToday['around'] ) {
				if( $iCurrTimeNow < $aToday['open_from'] ) $aOpenCloseState[vi_substr('0' . $aToday['open_from'], -4, 2) . ':' . vi_substr($aToday['open_from'], -2, 2)] = 'open_gen';
				if( $iCurrTimeNow < $aToday['open_to'] ) $aOpenCloseState[vi_substr('0' . $aToday['open_to'], -4, 2) . ':' . vi_substr($aToday['open_to'], -2, 2)] = 'closed_gen';
			}
			if( $aToday['pausa_from'] ){
				if( $iCurrTimeNow < $aToday['pausa_from'] ) $aOpenCloseState[vi_substr('0' . $aToday['pausa_from'], -4, 2) . ':' . vi_substr($aToday['pausa_from'], -2, 2)] = 'closed_pausa';
				if( $iCurrTimeNow < $aToday['pausa_to'] ) $aOpenCloseState[vi_substr('0' . $aToday['pausa_to'], -4, 2) . ':' . vi_substr($aToday['pausa_to'], -2, 2)] = 'open_pausa';
			}
		}
		if(count($aOpenCloseState)>1) {
			uksort( $aOpenCloseState, function($a,$b){return $a==$b?0:($a>$b?1:-1);});
		}

		//ðÀð┤ðÁÐüÐî ð▒Ðâð┤ÐâÐé Ðéð¥ð╗Ðîð║ð¥ ÐéðÁ ð┐ðÁÐÇð©ð¥ð┤Ðï, ð┤ð¥ ð║ð¥Ðéð¥ÐÇÐïÐà ÐüðÁð│ð¥ð┤ð¢ÐÅ ð▓ÐÇðÁð╝ÐÅ ðÁÐëðÁ ð¢ðÁ ð┤ð¥Ðêð╗ð¥
		if( $aOpenCloseState ) {
			$aOpenCloseState = json_encode(array('now'=>vi_substr('0' . $iCurrTimeNow, -4, 2).':'.vi_substr( $iCurrTimeNow, -2, 2),
				/*'now'=>'17:25',*/'now_s'=>date('s'),'wt'=>$aOpenCloseState));
		}

		return array('periods'=>$aResultPeriod, 'is_open_now'=>$iIsOpenNow, 'hash'=>md5($sHashLine),'states'=>$aOpenCloseState);
	}

	/**
	 * @param array $aDays  ð╝ð░ÐüÐüð©ð▓ ð▓ð©ð┤ð░ array( "ð┐ð¢-ð┐Ðé"=>'09:30-18:00','Cð▒,ð▓Ðü' => 'ð▓ÐïÐàð¥ð┤ð¢ð¥ð╣' );
	 */
	function worktime4DB_FromText( $aDays ){
//		echo __FUNCTION__.' -- ';
//		print_r( $aDays );



		$aAroundTitles = array('ð║ÐÇÐâð│ð╗ð¥ÐüÐâÐéð¥Ðçð¢ð¥','24h');
		$aMinsCorrect = array(0,15,30,45);
		$aModel		= array();
		foreach ( $aDays as $sPeriod => $sTime ) {
			$sPeriod = trim( vi_strtolower( $sPeriod ) );
			$sTime = str_replace('24:00','00:00',$sTime);
			if( $sTime == '00:00-00:00') $sTime = '24h';
			$aTime = explode('|', $sTime );
			$sTime = trim( vi_strtolower( $aTime[0] ) );
			$sPausa = isset($aTime[1])?trim($aTime[1]):'';
			$aDaySettings = array();

			if ( in_array( $sTime, $this->aDayOffTitles) ) {
				$aDaySettings['dayoff'] = true;
			} elseif ( in_array( $sTime, $aAroundTitles ) ){
				$aDaySettings['around'] = true;
			} elseif ( preg_match( '/(\d+):(\d+)\s*-\s*(\d+):(\d+)/u', $sTime, $aFromTo ) ) {
				$aDaySettings['open_from_hour'] = intval( $aFromTo[1] );
				foreach ( $aMinsCorrect as $iMinInterval ) if( $iMinInterval >= intval( $aFromTo[2] ) ) break;
				$aDaySettings['open_from_min'] = $iMinInterval;
				$aDaySettings['open_to_hour'] = intval( $aFromTo[3] );
				foreach ( $aMinsCorrect as $iMinInterval ) if( $iMinInterval >= intval( $aFromTo[4] ) ) break;
				$aDaySettings['open_to_min'] = $iMinInterval;
			} else {

				return '';
				die( ' sTime of workmodel incorrect '.$sPeriod . ' :: '. $sTime.' '.__LINE__);
			}

			if( !empty( $sPausa ) ){
				if ( preg_match( '/(\d+):(\d+)\s*-\s*(\d+):(\d+)/u', $sPausa, $aFromTo ) ) {
					$aDaySettings['pausa_from_hour'] = intval( $aFromTo[1] );
					foreach ( $aMinsCorrect as $iMinInterval ) if( $iMinInterval >= intval( $aFromTo[2] ) ) break;
					$aDaySettings['pausa_from_min'] = $iMinInterval;
					$aDaySettings['pausa_to_hour'] = intval( $aFromTo[3] );
					foreach ( $aMinsCorrect as $iMinInterval ) if( $iMinInterval >= intval( $aFromTo[4] ) ) break;
					$aDaySettings['pausa_to_min'] = $iMinInterval;
				} else {
					return '';
					die( ' sPausa of workmodel incorrect '.$sPeriod . ' :: '. $sPausa.' '.__LINE__);
				}
			}


			/**
			 * ð¡Ðéð¥ ð¢ð░ ð▓ÐüÐÅð║ð©ð╣ Ðüð╗ÐâÐçð░ð╣. ðòÐüð╗ð© ð▓ð┤ÐÇÐâð│ ð┐ðÁÐÇðÁð┤ð░ð¢ ð┐ðÁÐÇð©ð¥ð┤ ðÆðí-ðƒðØ ð©ð╗ð© ðíðæ-ðÆðó - Ðéð¥ ð▒Ðâð┤ðÁÐé ð┐ÐÇð¥ð╣ð┤ðÁð¢ Ðåð©ð║ð╗ ð¥Ðé 7 ð┤ð¥ 1, Ðéð░ð║ð©ð╝ ð¥ð▒ÐÇð░ðÀð¥ð╝ ð▓ÐüðÁ ð┤ð¢ð© ð┐ÐÇð©ð╝ÐâÐé ðÀð¢ð░ÐçðÁð¢ð©ÐÅ ÐìÐéð¥ð│ð¥ ð┐ðÁÐÇð©ð¥ð┤ð░
			 */
			$sPeriod = $this->worktimePeriodCorrect( $sPeriod );

			//var_dump(trim($sPeriod));
			if ( isset( $this->aDayTitles[$sPeriod] ) ) { //ðÁÐüð╗ð© ÐìÐéð¥ ð¥ð┤ð©ð¢ ð┤ðÁð¢Ðî
				$aModel[$this->aDayTitles[$sPeriod]] = $aDaySettings;
			} elseif ( preg_match( '/^(\w+)-(\w+)$/u', trim($sPeriod), $aDayOneFinal ) ) {
				$aDayOneFinal[1] = str_replace('||','|',preg_replace('/[^a-zð░-ÐÅ'.utfRegSymbAddList().']/iu','|',$aDayOneFinal[1]));
				$aDayOneFinal[2] = str_replace('||','|',preg_replace('/[^a-zð░-ÐÅ'.utfRegSymbAddList().']/iu','|',$aDayOneFinal[2]));

				if( !isset( $this->aDayTitles[$aDayOneFinal[1]])|| !isset($this->aDayTitles[$aDayOneFinal[2]] ) ) {
					ob_start();
					debug_print_backtrace();
					$s=ob_get_contents();
					ob_end_clean();
					/*
LEGACY_DEBUG_EMAIL_DISABLED: uncomment manually only if this real email notification is still required.
mail(CONF_DEBUG_EMAIL, ' CRITICAL DIE ERROR PARSE WORKTIME in the list '.$sPeriod, print_r($aDayOneFinal,1).__CLASS__.'->'.__FUNCTION__.' line: ' .__LINE__ . print_r($aDays,1) .print_r($_SERVER,1).$s);
*/
((class_exists('DebugNotificationLogger', false) || ((@include_once __DIR__ . '/../../_lib/DebugNotificationLogNormalizer.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationPolicy.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationLogger.php'))) ? (DebugNotificationLogger::logEmail(CONF_DEBUG_EMAIL, '[ATTENTION_LEGACY_EMAIL_DISABLED] ' . (' CRITICAL DIE ERROR PARSE WORKTIME in the list '.$sPeriod), print_r($aDayOneFinal,1).__CLASS__.'->'.__FUNCTION__.' line: ' .__LINE__ . print_r($aDays,1) .print_r($_SERVER,1).$s, array(
    'recipient_source' => 'CONF_DEBUG_EMAIL',
    'notification_code' => 'legacy_debug_email_cataloxy_flex_php_inc_firmaddress_class_765',
    'severity' => 'error',
    'source_file' => __FILE__,
    'source_line' => __LINE__,
    'context' => array(
        'attention_required' => true,
        'legacy_email_disabled' => true,
        'legacy_email_review_note' => 'Old direct mail() was disabled and commented. Review if real email notification is still required.',
    ),
)) ? true : false) : false);
					die(' error. incorrect day title in the list '.$sPeriod.' line:'.__LINE__);
				}
				foreach ( range($this->aDayTitles[$aDayOneFinal[1]], $this->aDayTitles[$aDayOneFinal[2]] ) as $iDayNum ) $aModel[$iDayNum] = $aDaySettings;
			} elseif ( vi_strpos($sPeriod, ',' ) !== false ) {
				$aDayTits = explode(',',$sPeriod);
				foreach ( $aDayTits as $sTitle ) {
					$sTitle = trim( $sTitle );
					if( !isset($this->aDayTitles[$sTitle]) ) {
						/*
LEGACY_DEBUG_EMAIL_DISABLED: uncomment manually only if this real email notification is still required.
mail(CONF_DEBUG_EMAIL, ' CRITICAL DIE ERROR PARSE WORKTIME ', __CLASS__.'->'.__FUNCTION__.' line: ' .__LINE__ . print_r($aDays,1).print_r($_SERVER,1));
*/
((class_exists('DebugNotificationLogger', false) || ((@include_once __DIR__ . '/../../_lib/DebugNotificationLogNormalizer.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationPolicy.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationLogger.php'))) ? (DebugNotificationLogger::logEmail(CONF_DEBUG_EMAIL, '[ATTENTION_LEGACY_EMAIL_DISABLED] ' . (' CRITICAL DIE ERROR PARSE WORKTIME '), __CLASS__.'->'.__FUNCTION__.' line: ' .__LINE__ . print_r($aDays,1).print_r($_SERVER,1), array(
    'recipient_source' => 'CONF_DEBUG_EMAIL',
    'notification_code' => 'legacy_debug_email_cataloxy_flex_php_inc_firmaddress_class_774',
    'severity' => 'error',
    'source_file' => __FILE__,
    'source_line' => __LINE__,
    'context' => array(
        'attention_required' => true,
        'legacy_email_disabled' => true,
        'legacy_email_review_note' => 'Old direct mail() was disabled and commented. Review if real email notification is still required.',
    ),
)) ? true : false) : false);
						die(' error. incorrect day title in '.$sPeriod.__LINE__);
					}
					$aModel[$this->aDayTitles[$sTitle]] = $aDaySettings;
				}
			} else {

				//ð▓ÐÇðÁð╝ðÁð¢ð¢ð¥ðÁ ÐâÐüð╗ð¥ð▓ð©ðÁ. ð▓ð¥ð¥ð▒ÐëðÁ ð┐ð¥ Ðàð¥ÐÇð¥ÐêðÁð╝Ðâ ð¢ð░ð┤ð¥ ð▒Ðï ÐÇð░ðÀð▒ð©ÐÇð░ÐéÐîÐüÐÅ
				if( CONF_DEFAULT_LANG !='en'){


//					ob_start();
//					print_r(debug_backtrace());
//					//print_r(debug_print_backtrace());
//					$sdbg=ob_get_contents();
//					ob_end_clean();

					/*
LEGACY_DEBUG_EMAIL_DISABLED: uncomment manually only if this real email notification is still required.
mail(CONF_DEBUG_EMAIL, ' CRITICAL DIE ERROR PARSE WORKTIME ', __CLASS__.'->'.__FUNCTION__.' line: ' .__LINE__ . print_r($aDays,1).print_r($_SERVER,1) . $sdbg);
*/
((class_exists('DebugNotificationLogger', false) || ((@include_once __DIR__ . '/../../_lib/DebugNotificationLogNormalizer.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationPolicy.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationLogger.php'))) ? (DebugNotificationLogger::logEmail(CONF_DEBUG_EMAIL, '[ATTENTION_LEGACY_EMAIL_DISABLED] ' . (' CRITICAL DIE ERROR PARSE WORKTIME '), __CLASS__.'->'.__FUNCTION__.' line: ' .__LINE__ . print_r($aDays,1).print_r($_SERVER,1) . $sdbg, array(
    'recipient_source' => 'CONF_DEBUG_EMAIL',
    'notification_code' => 'legacy_debug_email_cataloxy_flex_php_inc_firmaddress_class_791',
    'severity' => 'error',
    'source_file' => __FILE__,
    'source_line' => __LINE__,
    'context' => array(
        'attention_required' => true,
        'legacy_email_disabled' => true,
        'legacy_email_review_note' => 'Old direct mail() was disabled and commented. Review if real email notification is still required.',
    ),
)) ? true : false) : false);
					die( ' sDays of workmodel incorrect ' . $sPeriod . ' :: '. $sTime. ' '.__LINE__);
				}
			}
		}
		if( count($aModel) < 7 ) {
			if( CONF_DEFAULT_LANG !='en') {
				/*
LEGACY_DEBUG_EMAIL_DISABLED: uncomment manually only if this real email notification is still required.
mail(CONF_DEBUG_EMAIL, ' CRITICAL DIE ERROR PARSE WORKTIME ', __CLASS__ . '->' . __FUNCTION__ . ' line: ' . __LINE__ . print_r($aDays, 1) . print_r($_SERVER, 1));
*/
((class_exists('DebugNotificationLogger', false) || ((@include_once __DIR__ . '/../../_lib/DebugNotificationLogNormalizer.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationPolicy.php') && (@include_once __DIR__ . '/../../_lib/DebugNotificationLogger.php'))) ? (DebugNotificationLogger::logEmail(CONF_DEBUG_EMAIL, '[ATTENTION_LEGACY_EMAIL_DISABLED] ' . (' CRITICAL DIE ERROR PARSE WORKTIME '), __CLASS__ . '->' . __FUNCTION__ . ' line: ' . __LINE__ . print_r($aDays, 1) . print_r($_SERVER, 1), array(
    'recipient_source' => 'CONF_DEBUG_EMAIL',
    'notification_code' => 'legacy_debug_email_cataloxy_flex_php_inc_firmaddress_class_798',
    'severity' => 'error',
    'source_file' => __FILE__,
    'source_line' => __LINE__,
    'context' => array(
        'attention_required' => true,
        'legacy_email_disabled' => true,
        'legacy_email_review_note' => 'Old direct mail() was disabled and commented. Review if real email notification is still required.',
    ),
)) ? true : false) : false);
				die('error days count: ' . print_r($aModel, 1) . ' ' . __FUNCTION__ . ',' . __LINE__);
			}
		}
		return $aModel;
	}




	public function worktimePeriodCorrect( $sPeriod ) {
		if( preg_match( '/^(\w+)-(\w+)$/u', trim($sPeriod), $aDayOneFinal ) ) {
			if( isset($this->aDayTitles[$aDayOneFinal[1]]) && $this->aDayTitles[$aDayOneFinal[2]]) {
				if( $this->aDayTitles[$aDayOneFinal[1]] > $this->aDayTitles[$aDayOneFinal[2]] ) {
					$aPer = array();
					$aPeriodDays = array_merge(range($this->aDayTitles[$aDayOneFinal[1]],7),range(1,$this->aDayTitles[$aDayOneFinal[2]]));
					$aNum2Day =  array_flip( $this->aDayTitles );
					foreach ( $aPeriodDays as $iDay ) {
						$aPer[] = $aNum2Day[$iDay];
					}
					$sPeriod = implode(',',array_unique($aPer));
				}
			}
		}
		return $sPeriod;
	}



	//ð┐ÐÇð¥ð▓ðÁÐÇÐÅðÁð╝, ðÁÐüÐéÐî ð╗ð© ð¥Ðéð║ÐÇÐïÐéÐïðÁ Ðéð¥Ðçð║ð©	
	public function checkOpenAddressExists( &$aAddressList ) {
		$a4Foreach = array();
		//ðÁÐüð╗ð© ð┐ðÁÐÇðÁð┤ð░ð¢ ð¥ð┤ð©ð¢ ð▓Ðïð▒ÐÇð░ð¢ð¢Ðïð╣ ð░ð┤ÐÇðÁÐü, ð░ ð¢ðÁ Ðüð┐ð©Ðüð¥ð║
		if ( isset($aAddressList['json'] ) ) $a4Foreach[] = $aAddressList;
		else $a4Foreach = &$aAddressList; //ð©ð¢ð░ÐçðÁ Ðüð┐ð©Ðüð¥ð║
		
		//ð▒ðÁðÂð©ð╝ ð┐ð¥ Ðåð©ð║ð╗Ðâ
		foreach ( $a4Foreach as $aModel ) {
			//ðÁÐüð╗ð© ðÁÐüÐéÐî ð¥Ðéð║ÐÇÐïÐéÐïð╣ ð░ð┤ÐÇðÁÐü, ð▓ð¥ðÀð▓ÐÇð░Ðëð░ðÁð╝ ðÁð│ð¥ ID
			if ( $aModel['data']['is_open_now'] > 0 ) return  $aModel['data']['address_id'];
		}
		return false;
	}




	public function insertCataloxyCommunicationLink( &$sCommunicationString, $sLink ) {

		if( ( vi_strpos($sCommunicationString, 'http://')!==false || vi_strpos(  $sCommunicationString, 'https://')!==false ) &&
			( vi_strpos($sCommunicationString, '.cataloxy') === false&&vi_strpos($sCommunicationString, '://cataloxy') === false )
		) {
			if( vi_strpos( $sCommunicationString, "\nhttp" ) !== false ) {
				$sCommunicationString.= "\n";
			} else $sCommunicationString .= " ";
			$sCommunicationString .= $sLink;

		}
	}
	
	/**
	
	ð┐ÐÇð¥ð▓ðÁÐÇÐÅðÁð╝ ðÁÐüÐéÐî ð╗ð© Ðâ ÐìÐéð©Ðà Ðäð©ÐÇð╝ ÐÇð░Ðüð┐ð©Ðüð░ð¢ð©ÐÅ
	
	**/
	function firmsHasWorktime( $aFirmIDs ) {
		//if( isd() ) $this->_oAdo->debug=true;
		$sSQL	=	'SELECT WT.firm_id, WT.firm_id AS firm_id_2,  IFNULL( FO.address_id, -1 ) AS is_opened_now
					FROM cataloxy_firm_address_worktime AS WT
							LEFT JOIN cataloxy_firm_is_opened AS FO ON( FO.firm_id = WT.firm_id )
					WHERE WT.firm_id IN ('.implode(',',$aFirmIDs).')
					GROUP BY WT.firm_id
					ORDER BY is_opened_now DESC';
		return $this->_oAdo->GetAssoc( $sSQL );
	}



    /**
     * Schema.org openingHoursSpecification ð┤ð╗ÐÅ ð░ð┤ÐÇðÁÐüð░ ð║ð¥ð╝ð┐ð░ð¢ð©ð©.
     * ðæðÁÐÇÐæð╝ ð░ð┤ÐÇðÁÐü_id, ðÁÐüð╗ð© ð¢ðÁÐé ÔÇö fallback ð¢ð░ address_id=0 (ð║ð░ð║ ð▓ worktimeModelFull()).
     */
    public function getOpeningHoursSpecification(int $iFirmID, int $iAddressID = 0, int $iCityID = 0): array
    {
        // 1) Ðéð░ð╣ð╝ðÀð¥ð¢ð░ (ð║ð░ð║ ð▓ worktimeModelFull) :contentReference[oaicite:5]{index=5}
        if (!empty($iCityID)) {
            $aAddressCity = CSettings::i('CRegion')->getCityCache($iCityID);
            $this->setTimezone($aAddressCity['timezone_id']);
        }

        $ids = array_unique([0, (int)$iAddressID]);

        $sSQL = 'SELECT * FROM cataloxy_firm_address_worktime
             WHERE firm_id = ' . (int)$iFirmID . '
               AND address_id IN (' . implode(',', $ids) . ')
             ORDER BY address_id';

        if (!$oList = $this->_oAdo->Execute($sSQL)) return [];

        $aRows = [];
        while ($aRow = $oList->FetchRow()) {
            // ð┐ð¥ð┤ÐéÐÅð│ð©ð▓ð░ðÁð╝ ð╝ð¥ð┤ðÁð╗Ðî, ðÁÐüð╗ð© ðÁÐüÐéÐî (ð║ð░ð║ ð▓ worktimeModelFull) :contentReference[oaicite:6]{index=6}
            if (!empty($aRow['worktime_model_id'])) {
                if ($aWtModel = $this->getWTModelCache((int)$aRow['worktime_model_id'])) {
                    $aRow = array_merge($aRow, $aWtModel);
                }
            }
            $aRows[(int)$aRow['address_id']] = $aRow;
        }

        $aDB = $aRows[$iAddressID] ?? $aRows[0] ?? null;
        if (empty($aDB)) return [];

        // 2) ð¢ð¥ÐÇð╝ð░ð╗ð©ðÀð░Ðåð©ÐÅ ð▓ ð╝ð░ÐüÐüð©ð▓ ð┤ð¢ðÁð╣ (dayoff/around/pausa ð┐ÐÇð¥ÐüÐéð░ð▓ð╗ÐÅÐÄÐéÐüÐÅ ð▓ð¢ÐâÐéÐÇð©) :contentReference[oaicite:7]{index=7}
        $aDays = $this->worktimeGetFinalArray($aDB);

        // 3) ð║ð¥ð¢ð▓ðÁÐÇÐéð░Ðåð©ÐÅ ð▓ OpeningHoursSpecification
        return $this->_daysToOpeningHoursSpecification($aDays);
    }

    private function _daysToOpeningHoursSpecification(array $aDays): array
    {
        // DateTime->format('N'): 1=Mon ... 7=Sun (Ðâ ð▓ð░Ðü Ðéð░ð║ ðÂðÁ ð©Ðüð┐ð¥ð╗ÐîðÀÐâðÁÐéÐüÐÅ) :contentReference[oaicite:8]{index=8}
        $map = [
            1 => 'Monday',
            2 => 'Tuesday',
            3 => 'Wednesday',
            4 => 'Thursday',
            5 => 'Friday',
            6 => 'Saturday',
            7 => 'Sunday',
        ];

        $buckets = []; // key "opens|closes" => spec

        foreach ($aDays as $iDayNum => $d) {
            if (!empty($d['dayoff'])) continue;
            if (empty($map[$iDayNum])) continue;

            $intervals = [];

            // ðÁÐüð╗ð© ðÁÐüÐéÐî ð┐ðÁÐÇðÁÐÇÐïð▓ ÔÇö ð┤ðÁð╗ð░ðÁð╝ ð┤ð▓ð░ ð©ð¢ÐéðÁÐÇð▓ð░ð╗ð░ (ð┤ð¥ ð© ð┐ð¥Ðüð╗ðÁ ð┐ðÁÐÇðÁÐÇÐïð▓ð░)
            if (!empty($d['pausa']) && !empty($d['pausa_from']) && !empty($d['pausa_to'])) {
                $intervals[] = [(int)$d['open_from'], (int)$d['pausa_from']];
                $intervals[] = [(int)$d['pausa_to'], (int)$d['open_to']];
            } else {
                $intervals[] = [(int)$d['open_from'], (int)$d['open_to']];
            }

            foreach ($intervals as [$from, $to]) {
                if ($from === 0 && $to === 0) continue;

                // ð║ÐÇÐâð│ð╗ð¥ÐüÐâÐéð¥Ðçð¢ð¥
                if ($from === 0 && $to === 2359) {
                    $opens  = '00:00';
                    $closes = '23:59';
                } else {
                    $opens  = $this->_wtTimeToString($from);
                    $closes = $this->_wtTimeToString($to);
                }

                $key = $opens . '|' . $closes;

                if (!isset($buckets[$key])) {
                    $buckets[$key] = [
                        '@type' => 'OpeningHoursSpecification',
                        'dayOfWeek' => [],
                        'opens' => $opens,
                        'closes' => $closes,
                    ];
                }

                $buckets[$key]['dayOfWeek'][] = $map[$iDayNum];
            }
        }

        // Ðçð©ÐüÐéð©ð╝ ð┐ð¥ð▓Ðéð¥ÐÇÐï dayOfWeek
        foreach ($buckets as &$spec) {
            $spec['dayOfWeek'] = array_values(array_unique($spec['dayOfWeek']));
        }

        return array_values($buckets);
    }

    private function _wtTimeToString(int $t): string
    {
        $h = (int)floor($t / 100);
        $m = (int)($t % 100);
        return sprintf('%02d:%02d', $h, $m);
    }




    function cacheIsOpenNowFirms() {

		return $this->cacheIsOpenNowFirmsNew();

	}





    /**
     * ð×ð▒ð¢ð¥ð▓ð╗ÐÅðÁÐé ð░ÐéÐÇð©ð▒ÐâÐé is_open ð▓ Sphinx/Manticore ð┐ð¥ Ðüð┐ð©Ðüð║Ðâ firm_id.
     */
    function updateIsOpen(array $ids, int $value, string $index) {
        if (empty($ids)) return 0;

        $mysqli = sphinxql(); // mysqli-ð║ð¥ð¢ð¢ðÁð║Ðé ð║ 9306

        $chunkSize = 10000;
        $total = 0;

        foreach (array_chunk($ids, $chunkSize) as $chunk) {
            $list = implode(',', array_map('intval', $chunk));
            $sql  = "UPDATE $index SET is_open=".(int)$value." WHERE id IN ($list)";
            if (!$mysqli->query($sql)) {
                throw new RuntimeException('SphinxQL UPDATE failed: '.$mysqli->error);
            }
            $total += $mysqli->affected_rows;
        }

        return $total;
    }




    /**
     * ðƒðÁÐÇðÁÐüÐçÐæÐé ┬½ð║Ðéð¥ ð¥Ðéð║ÐÇÐïÐé ÐüðÁð╣Ðçð░Ðü┬╗ + Ðüð©ð¢ÐàÐÇð¥ð¢ð©ðÀð░Ðåð©ÐÅ ð░ÐéÐÇð©ð▒ÐâÐéð░ is_open ð▓ Sphinx.
     * - ðíÐçð©Ðéð░ðÁÐé Ðüð¢ð©ð╝ð¥ð║ ð¢ð░ ÐéðÁð║ÐâÐëÐâÐÄ ð╝ð©ð¢ÐâÐéÐâ ð┐ð¥ Ðéð░ð╣ð╝ðÀð¥ð¢ðÁ ÐÇðÁð│ð©ð¥ð¢ð░
     * - ðíð▓ð░ð┐ð░ðÁÐé Ðéð░ð▒ð╗ð©ÐåÐï (new -> current, old -> backup)
     * - ðíÐçð©Ðéð░ðÁÐé ð┤ðÁð╗ÐîÐéÐâ to_open / to_close ð© ð¥ð▒ð¢ð¥ð▓ð╗ÐÅðÁÐé Sphinx ð▒ð░ÐéÐçð░ð╝ð©
     * - ðöðÁð╗ð░ðÁÐé bootstrap, ðÁÐüð╗ð© ÐìÐéð¥ ð┐ðÁÐÇð▓Ðïð╣ ðÀð░ð┐ÐâÐüð║ (ð▓ ð©ð¢ð┤ðÁð║ÐüðÁ ð▓ÐüÐæ = 0)
     */
    public function cacheIsOpenNowFirmsNew()
    {
        global $aCountries;

        // ðÿð╝ÐÅ ð©ð¢ð┤ðÁð║Ðüð░(ð¥ð▓) Sphinx
        $indexName = '';
        if (CONF_USE_SPHINX_FIRMS) {
            $indexName = CONF_USE_SPHINX_FIRMS . '_firms';          // ð¢ð░ð┐ÐÇð©ð╝ðÁÐÇ: cataloxy_ru_firms
        }
        $deltaIndex = $indexName ? 'delta_' . $indexName : '';

        // ðæð╗ð¥ð║ð©ÐÇð¥ð▓ð║ð░ ð¥Ðé ð┐ð░ÐÇð░ð╗ð╗ðÁð╗Ðîð¢ÐïÐà ðÀð░ð┐ÐâÐüð║ð¥ð▓
        $gotLock = (int)$this->_oAdo->GetOne("SELECT GET_LOCK('rebuild_firm_is_opened', 1)");
        if ($gotLock !== 1) return false;

        try {
            // ðºÐéð¥ð▒Ðï GROUP_CONCAT ð¢ðÁ ÐâÐÇðÁðÀð░ð╗ÐüÐÅ ð¢ð░ ð┤ð╗ð©ð¢ð¢ÐïÐà Ðüð┐ð©Ðüð║ð░Ðà ð│ð¥ÐÇð¥ð┤ð¥ð▓
            $this->_oAdo->Execute('SET SESSION group_concat_max_len=1048576');

            // 1) ðíð▒ð¥ÐÇ ð¢ð¥ð▓ð¥ð╣ Ðéð░ð▒ð╗ð©ÐåÐï ÐüÐéð░ÐéÐâÐüð░ ð¥Ðéð║ÐÇÐïÐéð¥ÐüÐéð©
            $this->_oAdo->Execute('DROP TABLE IF EXISTS cataloxy_firm_is_opened_old');
            $this->_oAdo->Execute('DROP TABLE IF EXISTS cataloxy_firm_is_opened_new');
            $this->_oAdo->Execute('CREATE TABLE cataloxy_firm_is_opened_new LIKE cataloxy_firm_is_opened');

            $aRegions = CSettings::i('CRegion')->getList('region', $aCountries[1][2]);

            foreach ($aRegions as $aRegion) {
                $sCityList = $this->_oAdo->GetOne('SELECT GROUP_CONCAT(city_id) FROM cataloxy_cities WHERE region_id=' . (int)$aRegion['region_id']);
                if (!$sCityList) continue;

                $dt = new DateTime();
                $dt->setTimezone(new DateTimeZone($aRegion['timezone_id']));
                $iCurrTimeNow = $dt->format('Gi');      // 0..2359
                $iCurrDay     = (int)$dt->format('N');  // 1..7
                $sDayKey      = 'day' . $iCurrDay . '_';

                $sql = '
                INSERT IGNORE INTO cataloxy_firm_is_opened_new (firm_id, address_id, is_actual)
                SELECT DISTINCT
                       W.firm_id,
                       address_id,
                       1 AS is_actual
                FROM cataloxy_worktime_model WM
                JOIN cataloxy_firm_address_worktime W USING (worktime_model_id)
                WHERE
                      ' . $sDayKey . 'open_from != 3333
                  AND ' . $sDayKey . 'open_from <= ' . $iCurrTimeNow . '
                  AND ' . $sDayKey . 'open_to   >  ' . $iCurrTimeNow . '
                  AND (' . $sDayKey . 'pausa_from = 0
                       OR (' . $iCurrTimeNow . ' NOT BETWEEN ' . $sDayKey . 'pausa_from AND ' . $sDayKey . 'pausa_to-15))
                  AND W.wt_city_id IN (' . $sCityList . ')
            ';
                $this->_oAdo->Execute($sql);
            }

            // 2) ðÉÐéð¥ð╝ð░ÐÇð¢Ðïð╣ Ðüð▓ð░ð┐ Ðéð░ð▒ð╗ð©Ðå
            $this->_oAdo->Execute('
            RENAME TABLE
              cataloxy_firm_is_opened     TO cataloxy_firm_is_opened_old,
              cataloxy_firm_is_opened_new TO cataloxy_firm_is_opened
        ');

            if ($indexName) {
                // 3) ðöðÁð╗ÐîÐéð░ ð┐ð¥ firm_id (ð¢ð░Ðü ð©ð¢ÐéðÁÐÇðÁÐüÐâðÁÐé ┬½ðÁÐüÐéÐî ð╗ð© Ðâ Ðäð©ÐÇð╝Ðï Ðàð¥ÐéÐî ð¥ð┤ð©ð¢ ð¥Ðéð║ÐÇÐïÐéÐïð╣ ð░ð┤ÐÇðÁÐü┬╗)
                $this->_oAdo->Execute('DROP TEMPORARY TABLE IF EXISTS to_open');
                $this->_oAdo->Execute('DROP TEMPORARY TABLE IF EXISTS to_close');

                $this->_oAdo->Execute('
                CREATE TEMPORARY TABLE to_open (firm_id INT PRIMARY KEY)
                SELECT DISTINCT n.firm_id
                FROM cataloxy_firm_is_opened n
                LEFT JOIN cataloxy_firm_is_opened_old o USING (firm_id)
                WHERE o.firm_id IS NULL
            ');

                $this->_oAdo->Execute('
                CREATE TEMPORARY TABLE to_close (firm_id INT PRIMARY KEY)
                SELECT DISTINCT o.firm_id
                FROM cataloxy_firm_is_opened_old o
                LEFT JOIN cataloxy_firm_is_opened n USING (firm_id)
                WHERE n.firm_id IS NULL
            ');

                $openCnt  = (int)$this->_oAdo->GetOne('SELECT COUNT(*) FROM to_open');
                $closeCnt = (int)$this->_oAdo->GetOne('SELECT COUNT(*) FROM to_close');

                // 3a) Bootstrap ð┤ð╗ÐÅ ð┐ðÁÐÇð▓ð¥ð│ð¥ ðÀð░ð┐ÐâÐüð║ð░ (ð▓ ð©ð¢ð┤ðÁð║ÐüðÁ ð▓ÐüÐæ = 0)
                $needBootstrap = false;
                $openedNowRows = (int)$this->_oAdo->GetOne('SELECT COUNT(DISTINCT firm_id) FROM cataloxy_firm_is_opened');

                if ($openedNowRows > 0) {
                    $mysqli = sphinxql();

                    $sumBase  = 0;
                    $sumDelta = 0;

                    if ($res = $mysqli->query("SELECT SUM(is_open) s FROM $indexName")) {
                        $row = $res->fetch_row(); $sumBase = (int)$row[0];
                    }
                    if ($deltaIndex && $res = $mysqli->query("SELECT SUM(is_open) s FROM $deltaIndex")) {
                        $row = $res->fetch_row(); $sumDelta = (int)$row[0];
                    }

                    if (($sumBase + $sumDelta) === 0 && ($openCnt + $closeCnt) === 0) {
                        $needBootstrap = true;
                    }
                }

                // ÐàðÁð╗ð┐ðÁÐÇ: ð▒ð░ÐéÐçðÁð▓ð¥ ð¥ð▒ð¢ð¥ð▓ð╗ÐÅðÁð╝ ÐüÐÇð░ðÀÐâ ð▓ ð┤ð▓ð░ ð©ð¢ð┤ðÁð║Ðüð░
                $applyBatches = function (string $tableOrSql, int $value, bool $isSql = false) use ($indexName, $deltaIndex) {
                    $batch  = 10000;
                    $offset = 0;

                    while (true) {
                        $sql = $isSql
                            ? "SELECT firm_id FROM ($tableOrSql) x LIMIT $batch OFFSET $offset"
                            : "SELECT firm_id FROM $tableOrSql LIMIT $batch OFFSET $offset";

                        $rows = $this->_oAdo->GetCol($sql);
                        if (!$rows) break;

                        $this->updateIsOpen($rows, $value, $indexName);
                        if ($deltaIndex) {
                            $this->updateIsOpen($rows, $value, $deltaIndex);
                        }
                        $offset += $batch;
                    }
                };

                if ($needBootstrap) {
                    // ðƒð¥ð│ð░Ðüð©ð╝ ð▓ÐüðÁð╝ ð© ðÀð░ð┐ð¥ð╗ð¢ð©ð╝ ð©ðÀ ð░ð║ÐéÐâð░ð╗Ðîð¢ð¥ð│ð¥ Ðüð¢ð©ð╝ð║ð░
                    $mysqli = sphinxql();
                    $mysqli->query("UPDATE $indexName SET is_open=0 WHERE id>0");
                    if ($deltaIndex) $mysqli->query("UPDATE $deltaIndex SET is_open=0 WHERE id>0");

                    $applyBatches('SELECT DISTINCT firm_id FROM cataloxy_firm_is_opened ORDER BY firm_id', 1, true);
                } else {
                    // 4) ð×ð▒ÐïÐçð¢ð░ÐÅ ð┤ðÁð╗ÐîÐéð░
                    $applyBatches('to_open', 1);
                    $applyBatches('to_close', 0);
                }
            }

            // 5) ðºð©ÐüÐéð©ð╝ ð© ð┐ð¥ð┤Ðüð║ð░ðÀÐïð▓ð░ðÁð╝ ð¥ð┐Ðéð©ð╝ð©ðÀð░Ðéð¥ÐÇÐâ ÐüÐéð░Ðéð©ÐüÐéð©ð║Ðâ
            $this->_oAdo->Execute('DROP TABLE cataloxy_firm_is_opened_old');
            $this->_oAdo->Execute('ANALYZE TABLE cataloxy_firm_is_opened');

            return true;

        } finally {
            // ð×Ðéð┐ÐâÐüð║ð░ðÁð╝ ð╗ð¥ð║ ð▓ ð╗ÐÄð▒ð¥ð╝ Ðüð╗ÐâÐçð░ðÁ
            $this->_oAdo->Execute("SELECT RELEASE_LOCK('rebuild_firm_is_opened')");
        }
    }





	function ___cacheIsOpenNowFirmsNew() {
		global $aCountries;

        $gotLock = (int)$this->_oAdo->GetOne("SELECT GET_LOCK('rebuild_firm_is_opened', 1)");
        if ($gotLock !== 1) return false;

        try {
            // --- ðØðÉðºðÉðøð× ð░Ðéð¥ð╝ð░ÐÇð¢ð¥ð╣ ð┐ðÁÐÇðÁÐüÐéÐÇð¥ð╣ð║ð© cataloxy_firm_is_opened ---
            $this->_oAdo->Execute('DROP TABLE IF EXISTS cataloxy_firm_is_opened_new');
            $this->_oAdo->Execute('CREATE TABLE cataloxy_firm_is_opened_new LIKE cataloxy_firm_is_opened');

            $aRegions = CSettings::i('CRegion')->getList('region', $aCountries[1][2]);
            foreach ($aRegions as $aRegion) {
                $sCityList = $this->_oAdo->GetOne('SELECT GROUP_CONCAT(city_id) FROM cataloxy_cities WHERE region_id=' . (int)$aRegion['region_id']);
                if (!$sCityList) continue;

                $dt = new DateTime();
                $dt->setTimezone(new DateTimeZone($aRegion['timezone_id']));
                $iCurrTimeNow = $dt->format('Gi');       // 0..2359
                $iCurrDay = (int)$dt->format('N');   // 1..7
                $sDayKey = 'day' . $iCurrDay . '_';

                $sql = '
                    INSERT IGNORE INTO cataloxy_firm_is_opened_new (firm_id, address_id, is_actual)
                    SELECT
                        DISTINCT
                        W.firm_id,
                        address_id,
                        1 AS is_actual
                    FROM cataloxy_worktime_model WM
                    JOIN cataloxy_firm_address_worktime W USING (worktime_model_id)
                    WHERE
                          ' . $sDayKey . 'open_from != 3333
                      AND ' . $sDayKey . 'open_from <= ' . $iCurrTimeNow . '
                      AND ' . $sDayKey . 'open_to   >  ' . $iCurrTimeNow . '
                      AND (' . $sDayKey . 'pausa_from = 0 OR (' . $iCurrTimeNow . ' NOT BETWEEN ' . $sDayKey . 'pausa_from AND ' . $sDayKey . 'pausa_to-15))
                      AND W.wt_city_id IN (' . $sCityList . ')
                ';
                $this->_oAdo->Execute($sql);
            }

            /* ð×ð┤ð©ð¢ ÐÇð░ðÀ ð┐ð¥ð┤ð╝ðÁð¢ÐÅðÁð╝ Ðéð░ð▒ð╗ð©ÐåÐï ð░Ðéð¥ð╝ð░ÐÇð¢ð¥ */
            $this->_oAdo->Execute('
    RENAME TABLE
      cataloxy_firm_is_opened     TO cataloxy_firm_is_opened_old,
      cataloxy_firm_is_opened_new TO cataloxy_firm_is_opened
');
            $this->_oAdo->Execute('DROP TABLE cataloxy_firm_is_opened_old');
            $this->_oAdo->Execute('ANALYZE TABLE cataloxy_firm_is_opened'); // ð┐ð¥ ðÂðÁð╗ð░ð¢ð©ÐÄ

        }finally {
            // ð¥Ðéð┐ÐâÐüð║ð░ðÁð╝ ð╗ð¥ð║ ð▓ ð╗ÐÄð▒ð¥ð╝ Ðüð╗ÐâÐçð░ðÁ
            $this->_oAdo->Execute("SELECT RELEASE_LOCK('rebuild_firm_is_opened')");
        }







        return;





		$aFirmsOpenedNow = array();
		$i = 0;
		$aRegions = CSettings::i('CRegion')->getList('region',$aCountries[1][2]);

		$this->_oAdo->Execute('SET group_concat_max_len = 2000096;');

		foreach ( $aRegions as $aRegion ) {
			$sSQL	=	'SELECT GROUP_CONCAT(city_id) FROM cataloxy_cities WHERE region_id = '. $aRegion['region_id'];
			$sCityList = $this->_oAdo->GetOne( $sSQL );
			if( !$sCityList ){
				//mail('za.vetu@gmail.com','test',__FILE__.' ln: '.__LINE__ .' '. $sSQL.' '. print_r( $_SERVER ,1) );
				//ðÁÐëðÁ ð¢ðÁÐé ð│ð¥ÐÇð¥ð┤ð¥ð▓  ð▓ ÐÇðÁð│ð©ð¥ð¢ðÁ
				continue;
			}
			$datetime = new DateTime();
			$datetime->setTimezone(new DateTimeZone( $aRegion['timezone_id'] ) );
			$iCurrTimeNow 	= $datetime->format('Gi');
			$iCurrDay  		= $datetime->format('N');
			$sDayKey = 'day'.$iCurrDay.'_';
			/*
			$sWorktimeModelList = $this->_oAdo->GetOne('SELECT GROUP_CONCAT(worktime_model_id)
									FROM cataloxy_worktime_model WHERE
									'.$sDayKey.'open_from != 3333 AND
									'.$sDayKey.'open_from <= '	.$iCurrTimeNow.' AND
									'.$sDayKey.'open_to > '.$iCurrTimeNow.' AND
									( '.$sDayKey.'pausa_from = 0 OR ( '.$iCurrTimeNow.' NOT BETWEEN '.$sDayKey.'pausa_from AND '.$sDayKey.'pausa_to-15 ) )');
			*/




			$sSQL = 'SELECT W.firm_id, W.address_id
					FROM
						cataloxy_worktime_model AS WM
						  	JOIN cataloxy_firm_address_worktime AS W USING(worktime_model_id)
						  		/* JOIN cataloxy_firm AS FA USING( firm_id ) */
					WHERE
									'.$sDayKey.'open_from != 3333 AND
									'.$sDayKey.'open_from <= '	.$iCurrTimeNow.' AND
									'.$sDayKey.'open_to > '.$iCurrTimeNow.' AND
									( '.$sDayKey.'pausa_from = 0 OR ( '.$iCurrTimeNow.' NOT BETWEEN '.$sDayKey.'pausa_from AND '.$sDayKey.'pausa_to-15 ) ) AND
							/* FA.city_id */ W.wt_city_id IN( '.$sCityList.')
					GROUP BY W.firm_id
					ORDER BY W.address_id
					';

			//echo '
';
			$oRegionFirmList = $this->_oAdo->Execute($sSQL);
			//die;

			$iInsertIDsPerTransaction = 1000;

			while ( $aList = $oRegionFirmList -> FetchRow() ) {
				$i++;
				$aFirmsOpenedNow[intval($i/$iInsertIDsPerTransaction)][$aList['firm_id']] = $aList['address_id'];
			}
		}




		if( $aFirmsOpenedNow ) {

            do {
                $this->_oAdo->Execute('UPDATE `cataloxy_firm_is_opened` SET is_actual = 0 WHERE is_actual = 1 LIMIT 50000');
                $affected = $this->_oAdo->Affected_Rows();
            } while ($affected > 0);

			$sSQL = 'INSERT INTO cataloxy_firm_is_opened (firm_id,address_id,is_actual) VALUES ';
			foreach ( $aFirmsOpenedNow as $i => $aFirms ) {
				$aSQL	=	array();
				foreach ( $aFirms as $iFirmID=>$iAddressID ) {
					$aSQL[]	= '('.$iFirmID.','.$iAddressID.',1)';
				}
				$this->_oAdo->Execute( $sSQL . implode(',', $aSQL ) .
                    ' ON DUPLICATE KEY UPDATE
                      address_id = VALUES(address_id),
                      is_actual = VALUES(is_actual); ' );
			}
			$this->_oAdo->Execute('DELETE FROM `cataloxy_firm_is_opened` WHERE is_actual = 0');
		}
	}
}