Бизнес в области промбезопасности, сертификации продукции. Поддержка корпоративного портала ( bitrix ). Интеграция телефонии OkTell.

Поставка запчастей. Загрузка фактических продаж и планов в vTigerCRM из BI Pentaho и 1С8. Вывод динамики продаж по менеджерам.

Компания по сбору мусора. Отчеты для контроля оперативной работы менеджеров, операторов, объема продаж, долгов клиентов, расчета зарплаты, бонусов. Обмен данными между корпоративной CRM системой ( Bitrix24 ) и 1С7, 1C8. Взаимодействие с телефонией ( Asterisk )

Управление коммерческой недвижимостью в Санкт-Петербурге. Интерактивные карты ТЦ "Французский бульвар", "5 Озер", "СитиМолл", "Лондон-Молл". frbulvar.ru/magaziny trk-5ozer.ru/magaziny

Внедрение vTiger, интеграция с 1С, получение данных по ИНН из федеральной базы.

Доработка корпоративного портала на bitrix24 с функционалом CRM, ERP. Оптимизация базы данных, бизнес-процессов, документооборота, разработка отчетов ( финансовые итоги, прогнозы, расчет зарплаты )

Производство систем сигнализации и контроля доступа. Доработка Magento магазина

Финансовые услуги. Внедрение SugarCRM, доработка ролевой системы доступа

Внедрение SugarCRM. Импорт cобытий, студентов из excel файлов различного формата.

Строительная компания. Доработка TerraSoft CRM. Автоматизация подбора объектов, расчета стоимости по БТИ, согласования договоров. Экспорт платежей в Navision

Разработка сайта ( simplaCms ), интеграция со специализированной конфигурацией , настройка учета в разрезе характеристик ( размеры, пробы ) и поставщиков, оптимизация БД

Поставка ПО. Разработка новой версии магазина ( bitrix ). Интеграция с Google Analytics, Assist, 1С. Хронологический импорт цен. Учет лицензий.

namespace iteamo\framework;
require_once(__DIR__ . '/core/app.php');
require_once(__DIR__ . '/libs/traits/withSingleton.php');
/**
 *
 */
class app extends core\app{
public function getLib($key = '', $arParams = [], $arOptions = ['checkParent' => true]) {
  $objLib = parent::getLib($key, $arParams);
  //
  if ($arOptions['checkParent'] && empty($objLib)) {
    if ($this->arClass['name'] != __class__) {
      $parentClass = $this->arClass['parent'];
      $objLib = $parentClass::get()->getLib($key, $arParams, $arOptions);
    }
  }
  //
  return $objLib;
}
//
public function getView($key = '', $arData = [], $arOptions = ['checkParent' => false]) {
  $strView = parent::getView($key, $arData);
  //
  if ($arOptions['checkParent'] && is_null($strView)) {
    if ($this->arClass['name'] != __class__) {
        $parentClass = $this->arClass['parent'];
        $strView = $parentClass::get()->getView($key, $arData, $arOptions);
    }
  }
  //
  return $strView;
}
static public function parsePaths($arItem = []) {
  $arItemResult = [];
  foreach($arItem as $key => $value) {
    if (stripos('prefix' . $key, '[')) {
      $fullPath = '[' . substr_replace($key, '][', stripos($key, '['), 1);
      eval("\$arItemResult" . $fullPath . " = \$value;");
    } else $arItemResult[$key] = $value;
  }
  return $arItemResult;
}
request = {
  getDataFromUrl: function(url) {
    var arData = {};
    if(typeof url != 'undefined' && url.indexOf('?')!== -1) {
      var urlSplit = url.split('?');
      var queryString = urlSplit[1];
      var queryParameters = queryString.split('&');
      for(var index=0; index < queryParameters.length; index++) {
      	var queryParam = queryParameters[index];
      	var queryParamComponents = queryParam.split('=');
      	arData[queryParamComponents[0]] = queryParamComponents[1];
      }
    }
    return arData;
  },
  send: function(path, arData, arParams) {
    if (empty(arData)) arParams = {};
    if (empty(arParams)) arParams = {};
    //
    arParamsDefault = {
      dataType: 'json',
      type: 'GET',
    };
    arParams = jQuery.extend(false, {}, arParamsDefault, arParams);
    //
    var aDeferred = jQuery.Deferred();
		var success = function(data, status, jqXHR) {
      aDeferred.resolve(data);
		}
		var error = function(jqXHR, textStatus, errorThrown){
      aDeferred.reject(textStatus, errorThrown);
		}
    //
    var arDataFromUrl = this.getDataFromUrl(path);
    arData = jQuery.extend(false, {}, arData, arDataFromUrl);
    arParams.data = arData;
    arParams.url = path;
    arParams.timeout = 30000;
		arParams.success = success;
		arParams.error = error;
    //
		jQuery.ajax(arParams);
    //
    return aDeferred.promise();
  },
};
  
templater = {
  parse : function(strTemplate, arData) {
    var strParsedTemplate =
      strTemplate.replace(/\{([a-zA-Z0-9 ]*)\}/g, function(m, key) {
        result = arData[key.trim()];
        return result;
    });
    return strParsedTemplate;
  }
};
init: function (context) {
  window.$this = (context != undefined)?context:this;
  $this.cancelDefaultModulePolling();
  $this.parent.init($this);
},
isPageToInitPhoneLinks: function() {
  var result = false;
  var url = window.location.toString();
  if (/(Leads|Contacts|Accounts|PBXManager)/i.test(url)) {
    result = true;
  }
  return result;
},
isPageToInitCallListeningRecords: function() {
  return $this.isPageToInitPhoneLinks();
},
startCallNotify: function(arResult) {
  var params = {'type' : 'error', 'text' :  app.vtranslate('JS_PBX_OUTGOING_FAILURE')};
  if(arResult.status){
    params = {'type' : 'info', 'text' :  app.vtranslate('JS_PBX_OUTGOING_SUCCESS')};
  } else {
    if(!empty(arResult.arErrors)){
      params.text += ': ' + implode(';', arResult.arErrors);
    }
  }
  notification.show(params);
},
namespace iteamo\framework\libs\traits;
use \iteamo\framework\app;
trait withSingleton {
static public function get($arParams = []) {
  static $objInstances = [];
  $class = get_called_class();
  if (empty($objInstances[$class])) {
    $objInstances[$class] = new $class($arParams);
  }
  return $objInstances[$class];
}
}
public function update($arItem = []) {
  $count = false;
  $arItem = $this->prepareData($arItem);
  $arItems = self::filter($this->arItems, $this->arFilters);
  foreach($arItems as $key => $arItem) {
    $this->arItems[$key] = arrays::mergeUpdate($this->arItems[$key], $arItem);
  }
  $count = count($arItems);
  $this->reset();
  //
  return $count;
}


class entity {
use \iteamo\framework\libs\traits\withEntityInterface{
  \iteamo\framework\libs\traits\withEntityInterface::getItem as traitGetItem;
  \iteamo\framework\libs\traits\withEntityInterface::prepareData as traitPrepareData;
  \iteamo\framework\libs\traits\withEntityInterface::filter as traitFilter;
}
public $arCorrespondence = [];
public $table = '';
public $moduleId = 0;
//
private $dbQueryDriver = null;
/**
 *
 */
public function __construct() {
  include_once 'include/Webservices/Utils.php';
  $this->dbQueryDriver = \iteamo\framework\init::getLib('database/queryDrivers/sql');
}
/**
 *
 */
function filter($arFilters = array()) {
  if (!empty($arFilters['anyPhone'])) {
    $objDb = \PearDatabase::getInstance();