예제 #1
0
 /** @return array */
 public function getList(array $params)
 {
     $group = isset($params['group']) ? strtoupper($params['group']) : '';
     if ($group !== '' && $group !== self::GROUP_BY_USER && $group !== self::GROUP_BY_DATE) {
         $group = '';
     }
     /** @var Filter $filter */
     $filter = isset($params['filter']) ? $params['filter'] : null;
     if (!$filter instanceof Filter) {
         throw new Main\ObjectNotFoundException("The 'filter' is not found in params.");
     }
     $semanticID = $filter->getExtraParam('semanticID', PhaseSemantics::UNDEFINED);
     $isFinalSemantics = PhaseSemantics::isFinal($semanticID);
     $group = isset($params['group']) ? strtoupper($params['group']) : '';
     if ($group !== '' && $group !== self::GROUP_BY_USER && $group !== self::GROUP_BY_DATE) {
         $group = '';
     }
     /** @var array $select */
     $select = isset($params['select']) && is_array($params['select']) ? $params['select'] : array();
     $name = '';
     $aggregate = '';
     if (!empty($select)) {
         $selectItem = $select[0];
         if (isset($selectItem['name'])) {
             $name = $selectItem['name'];
         }
         if (isset($selectItem['aggregate'])) {
             $aggregate = strtoupper($selectItem['aggregate']);
         }
     }
     if ($name === '') {
         $name = 'INVOICE_SUM';
     }
     if ($aggregate !== '' && !in_array($aggregate, array('SUM', 'COUNT', 'MAX', 'MIN'))) {
         $aggregate = '';
     }
     $permissionSql = '';
     if ($this->enablePermissionCheck) {
         $permissionSql = $this->preparePermissionSql();
         if ($permissionSql === false) {
             //Access denied;
             return array();
         }
     }
     $period = $filter->getPeriod();
     $periodStartDate = $period['START'];
     $periodEndDate = $period['END'];
     $query = new Query(DealInvoiceStatisticsTable::getEntity());
     $query->addSelect($name);
     if ($aggregate !== '') {
         if ($aggregate === 'COUNT') {
             $query->registerRuntimeField('', new ExpressionField($name, "COUNT(*)"));
         } else {
             $query->registerRuntimeField('', new ExpressionField($name, "{$aggregate}({$name})"));
         }
     }
     $query->setTableAliasPostfix('_s2');
     $subQuery = new Query(DealInvoiceStatisticsTable::getEntity());
     $subQuery->setTableAliasPostfix('_s1');
     $subQuery->addSelect('OWNER_ID');
     $subQuery->addFilter('>=END_DATE', $periodStartDate);
     $subQuery->addFilter('<=START_DATE', $periodEndDate);
     //$subQuery->addFilter('<=CREATED_DATE', $periodEndDate);
     if ($semanticID !== PhaseSemantics::UNDEFINED) {
         $subQuery->addFilter('=STAGE_SEMANTIC_ID', $semanticID);
     }
     if ($this->enablePermissionCheck && is_string($permissionSql) && $permissionSql !== '') {
         $subQuery->addFilter('@OWNER_ID', new SqlExpression($permissionSql));
     }
     $responsibleIDs = $filter->getResponsibleIDs();
     if (!empty($responsibleIDs)) {
         $subQuery->addFilter('@RESPONSIBLE_ID', $responsibleIDs);
     }
     $subQuery->addGroup('OWNER_ID');
     $subQuery->addSelect('MAX_CREATED_DATE');
     $subQuery->registerRuntimeField('', new ExpressionField('MAX_CREATED_DATE', 'MAX(CREATED_DATE)'));
     $query->registerRuntimeField('', new ReferenceField('M', Base::getInstanceByQuery($subQuery), array('=this.OWNER_ID' => 'ref.OWNER_ID', '=this.CREATED_DATE' => 'ref.MAX_CREATED_DATE'), array('join_type' => 'INNER')));
     $sort = isset($params['sort']) && is_array($params['sort']) && !empty($params['sort']) ? $params['sort'] : null;
     if ($sort) {
         foreach ($sort as $sortItem) {
             if (isset($sortItem['name'])) {
                 $query->addOrder($sortItem['name'], isset($sortItem['order']) ? $sortItem['order'] : 'asc');
             }
         }
     }
     if ($group !== '') {
         if ($group === self::GROUP_BY_USER) {
             $query->addSelect('RESPONSIBLE_ID');
             $query->addGroup('RESPONSIBLE_ID');
         } else {
             if ($group === self::GROUP_BY_DATE) {
                 if ($isFinalSemantics) {
                     $query->addSelect('END_DATE', 'D');
                     $query->addGroup('END_DATE');
                     if (!$sort) {
                         $query->addOrder('END_DATE', 'ASC');
                     }
                 } else {
                     $query->addSelect('CREATED_DATE', 'D');
                     $query->addGroup('CREATED_DATE');
                     if (!$sort) {
                         $query->addOrder('CREATED_DATE', 'ASC');
                     }
                 }
             }
         }
     }
     $dbResult = $query->exec();
     //Trace('sql', Query::getLastQuery(), 1);
     $result = array();
     if ($group === self::GROUP_BY_DATE) {
         while ($ary = $dbResult->fetch()) {
             $ary['DATE'] = $ary['D']->format('Y-m-d');
             unset($ary['D']);
             if ($ary['DATE'] === '9999-12-31') {
                 //Skip empty dates
                 continue;
             }
             $result[] = $ary;
         }
     } elseif ($group === self::GROUP_BY_USER) {
         $userIDs = array();
         while ($ary = $dbResult->fetch()) {
             $userID = $ary['RESPONSIBLE_ID'] = (int) $ary['RESPONSIBLE_ID'];
             if ($userID > 0 && !isset($userNames[$userID])) {
                 $userIDs[] = $userID;
             }
             $result[] = $ary;
         }
         $userNames = self::prepareUserNames($userIDs);
         foreach ($result as &$item) {
             $userID = $item['RESPONSIBLE_ID'];
             $item['USER_ID'] = $userID;
             $item['USER'] = isset($userNames[$userID]) ? $userNames[$userID] : "[{$userID}]";
             unset($item['RESPONSIBLE_ID']);
         }
         unset($item);
     } else {
         while ($ary = $dbResult->fetch()) {
             $result[] = $ary;
         }
     }
     return $result;
 }
예제 #2
0
 public static function register($ownerID, array $entityFields = null, array $options = null)
 {
     if (!is_int($ownerID)) {
         $ownerID = (int) $ownerID;
     }
     if ($ownerID <= 0) {
         throw new Main\ArgumentException('Owner ID must be greater than zero.', 'ownerID');
     }
     if (!is_array($options)) {
         $options = array();
     }
     if (!is_array($entityFields)) {
         $dbResult = \CCrmDeal::GetListEx(array(), array('=ID' => $ownerID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('ID', 'STAGE_ID', 'ASSIGNED_BY_ID', 'BEGINDATE', 'CLOSEDATE'));
         $entityFields = is_object($dbResult) ? $dbResult->Fetch() : null;
         if (!is_array($entityFields)) {
             return false;
         }
     }
     $stageID = isset($entityFields['STAGE_ID']) ? $entityFields['STAGE_ID'] : '';
     if ($stageID === '') {
         return false;
     }
     $responsibleID = isset($entityFields['ASSIGNED_BY_ID']) ? (int) $entityFields['ASSIGNED_BY_ID'] : 0;
     $startDate = self::parseDateString(isset($entityFields['BEGINDATE']) ? $entityFields['BEGINDATE'] : '');
     if ($startDate === null) {
         $startDate = new Date();
     }
     $endDate = self::parseDateString(isset($entityFields['CLOSEDATE']) ? $entityFields['CLOSEDATE'] : '');
     if ($endDate === null) {
         $endDate = new Date('9999-12-31', 'Y-m-d');
     }
     $time = isset($options['TIME']) ? $options['TIME'] : null;
     if ($time === null) {
         $time = new DateTime();
     }
     $month = (int) $time->format('m');
     $quarter = $month <= 3 ? 1 : ($month <= 6 ? 2 : ($month <= 9 ? 3 : 4));
     $year = (int) $time->format('Y');
     $startMonth = (int) $startDate->format('m');
     $startQuarter = $startMonth <= 3 ? 1 : ($startMonth <= 6 ? 2 : ($startMonth <= 9 ? 3 : 4));
     $startYear = (int) $startDate->format('Y');
     $endMonth = (int) $endDate->format('m');
     $endQuarter = $endMonth <= 3 ? 1 : ($endMonth <= 6 ? 2 : ($endMonth <= 9 ? 3 : 4));
     $endYear = (int) $endDate->format('Y');
     $semanticID = \CCrmDeal::GetSemanticID($stageID);
     $isNew = isset($options['IS_NEW']) ? (bool) $options['IS_NEW'] : false;
     $typeID = PhaseSemantics::isFinal($semanticID) ? HistoryEntryType::FINALIZATION : ($isNew ? HistoryEntryType::CREATION : HistoryEntryType::MODIFICATION);
     $date = Date::createFromTimestamp($time->getTimestamp());
     $isLost = PhaseSemantics::isLost($semanticID);
     $latest = self::getLatest($ownerID);
     if ($latest['STAGE_ID'] === $stageID) {
         return false;
     }
     $result = DealStageHistoryTable::add(array('TYPE_ID' => $typeID, 'OWNER_ID' => $ownerID, 'CREATED_TIME' => $time, 'CREATED_DATE' => $date, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'PERIOD_YEAR' => $year, 'PERIOD_QUARTER' => $quarter, 'PERIOD_MONTH' => $month, 'START_PERIOD_YEAR' => $startYear, 'START_PERIOD_QUARTER' => $startQuarter, 'START_PERIOD_MONTH' => $startMonth, 'END_PERIOD_YEAR' => $endYear, 'END_PERIOD_QUARTER' => $endQuarter, 'END_PERIOD_MONTH' => $endMonth, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_ID' => $stageID, 'STAGE_SEMANTIC_ID' => $semanticID, 'IS_LOST' => $isLost ? 'Y' : 'N'));
     if ($result->isSuccess() && $result->getId() > 0 && is_array($latest) && (int) $latest['TYPE_ID'] === HistoryEntryType::FINALIZATION) {
         DealStageHistoryTable::delete($latest['ID']);
     }
     return true;
 }
 /**
  * @return boolean
  */
 public static function register($ownerID, array $entityFields = null, array $options = null)
 {
     if (!is_int($ownerID)) {
         $ownerID = (int) $ownerID;
     }
     if ($ownerID <= 0) {
         throw new Main\ArgumentException('Owner ID must be greater than zero.', 'ownerID');
     }
     if (!is_array($options)) {
         $options = array();
     }
     $date = isset($options['DATE']) ? $options['DATE'] : null;
     if ($date === null) {
         $date = new Date();
     }
     $day = (int) $date->format('d');
     $month = (int) $date->format('m');
     $quarter = $month <= 3 ? 1 : ($month <= 6 ? 2 : ($month <= 9 ? 3 : 4));
     $year = (int) $date->format('Y');
     if (!is_array($entityFields)) {
         $dbResult = \CCrmDeal::GetListEx(array(), array('=ID' => $ownerID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('STAGE_ID', 'ASSIGNED_BY_ID', 'BEGINDATE', 'CLOSEDATE'));
         $entityFields = is_object($dbResult) ? $dbResult->Fetch() : null;
         if (!is_array($entityFields)) {
             return false;
         }
     }
     $stageID = isset($entityFields['STAGE_ID']) ? $entityFields['STAGE_ID'] : '';
     $semanticID = \CCrmDeal::GetSemanticID($stageID);
     $isLost = PhaseSemantics::isLost($semanticID);
     $responsibleID = isset($entityFields['ASSIGNED_BY_ID']) ? (int) $entityFields['ASSIGNED_BY_ID'] : 0;
     $callQty = 0;
     $meetingQty = 0;
     $emailQty = 0;
     $startTime = new DateTime($date->format(DateTime::getFormat()));
     $endTime = new DateTime($date->format(DateTime::getFormat()));
     $endTime->setTime(23, 59, 59);
     $query = new Query(Crm\ActivityTable::getEntity());
     $query->addSelect('TYPE_ID');
     $query->registerRuntimeField('', new ExpressionField('QTY', 'COUNT(*)'));
     $query->addSelect('QTY');
     $query->addFilter('=COMPLETED', 'Y');
     $query->addFilter('>=DEADLINE', $startTime);
     $query->addFilter('<=DEADLINE', $endTime);
     $query->addGroup('TYPE_ID');
     $subQuery = new Query(Crm\ActivityBindingTable::getEntity());
     $subQuery->addSelect('ACTIVITY_ID');
     $subQuery->addFilter('=OWNER_TYPE_ID', \CCrmOwnerType::Deal);
     $subQuery->addFilter('=OWNER_ID', $ownerID);
     $query->registerRuntimeField('', new ReferenceField('B', Base::getInstanceByQuery($subQuery), array('=this.ID' => 'ref.ACTIVITY_ID'), array('join_type' => 'INNER')));
     $dbResult = $query->exec();
     while ($stats = $dbResult->fetch()) {
         $typeID = isset($stats['TYPE_ID']) ? (int) $stats['TYPE_ID'] : 0;
         $qty = isset($stats['QTY']) ? (int) $stats['QTY'] : 0;
         if ($typeID === \CCrmActivityType::Call) {
             $callQty = $qty;
         } elseif ($typeID === \CCrmActivityType::Meeting) {
             $meetingQty = $qty;
         } elseif ($typeID === \CCrmActivityType::Email) {
             $emailQty = $qty;
         }
     }
     if ($callQty === 0 && $meetingQty === 0 && $emailQty === 0) {
         DealActivityStatisticsTable::delete(array('OWNER_ID' => $ownerID, 'DEADLINE_DATE' => $date));
         return true;
     }
     $present = self::get($ownerID, $date);
     if (is_array($present)) {
         if ($responsibleID === (int) $present['RESPONSIBLE_ID'] && $stageID === $present['STAGE_ID'] && $callQty === (int) $present['CALL_QTY'] && $meetingQty === (int) $present['MEETING_QTY'] && $emailQty === (int) $present['EMAIL_QTY']) {
             return false;
         }
         if ($responsibleID !== (int) $present['RESPONSIBLE_ID']) {
             DealActivityStatisticsTable::synchronize($ownerID, array('RESPONSIBLE_ID' => $responsibleID));
         }
     }
     $data = array('OWNER_ID' => $ownerID, 'DEADLINE_DATE' => $date, 'DEADLINE_YEAR' => $year, 'DEADLINE_QUARTER' => $quarter, 'DEADLINE_MONTH' => $month, 'DEADLINE_DAY' => $day, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_SEMANTIC_ID' => $semanticID, 'STAGE_ID' => $stageID, 'IS_LOST' => $isLost ? 'Y' : 'N', 'CALL_QTY' => $callQty, 'MEETING_QTY' => $meetingQty, 'EMAIL_QTY' => $emailQty);
     DealActivityStatisticsTable::upsert($data);
     return true;
 }
예제 #4
0
			BX.CrmWidgetManager.filter = <?php 
echo CUtil::PhpToJSObject($arResult['WIDGET_FILTER']);
?>
;

			BX.CrmWidgetDataPreset.items = <?php 
echo CUtil::PhpToJSObject(Crm\Widget\Data\DataSourceFactory::getPresets());
?>
;
			BX.CrmWidgetDataPreset.notSelected = "<?php 
echo GetMessageJS("CRM_WGT_PRESET_NOT_SELECTED");
?>
";

			BX.CrmPhaseSemantics.descriptions = <?php 
echo CUtil::PhpToJSObject(Crm\PhaseSemantics::getAllDescriptions());
?>
;
			BX.CrmWidgetColorScheme.descriptions =
			{
				red: "<?php 
echo GetMessageJS("CRM_WGT_COLOR_RED");
?>
",
				green: "<?php 
echo GetMessageJS("CRM_WGT_COLOR_GREEN");
?>
",
				blue: "<?php 
echo GetMessageJS("CRM_WGT_COLOR_BLUE");
?>
 /**
  * @return boolean
  */
 public static function synchronize($ownerID, array $entityFields = null)
 {
     if (!is_int($ownerID)) {
         $ownerID = (int) $ownerID;
     }
     if ($ownerID <= 0) {
         throw new Main\ArgumentException('Owner ID must be greater than zero.', 'ownerID');
     }
     if (!is_array($entityFields)) {
         $dbResult = \CCrmDeal::GetListEx(array(), array('=ID' => $ownerID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('STAGE_ID', 'ASSIGNED_BY_ID', 'BEGINDATE', 'CLOSEDATE', 'OPPORTUNITY', 'CURRENCY_ID'));
         $entityFields = is_object($dbResult) ? $dbResult->Fetch() : null;
         if (!is_array($entityFields)) {
             return false;
         }
     }
     $stageID = isset($entityFields['STAGE_ID']) ? $entityFields['STAGE_ID'] : '';
     $semanticID = \CCrmDeal::GetSemanticID($stageID);
     $isLost = PhaseSemantics::isLost($semanticID);
     $responsibleID = isset($entityFields['ASSIGNED_BY_ID']) ? (int) $entityFields['ASSIGNED_BY_ID'] : 0;
     /** @var Date $startDate */
     $startDate = self::parseDateString(isset($entityFields['BEGINDATE']) ? $entityFields['BEGINDATE'] : '');
     if ($startDate === null) {
         $startDate = new Date();
     }
     /** @var Date $endDate */
     $endDate = self::parseDateString(isset($entityFields['CLOSEDATE']) ? $entityFields['CLOSEDATE'] : '');
     if ($endDate === null) {
         $endDate = new Date('9999-12-31', 'Y-m-d');
     }
     $sum = isset($entityFields['OPPORTUNITY']) ? (double) $entityFields['OPPORTUNITY'] : 0.0;
     $currencyID = isset($entityFields['CURRENCY_ID']) ? $entityFields['CURRENCY_ID'] : '';
     if ($currencyID === '') {
         $currencyID = \CCrmCurrency::GetBaseCurrencyID();
     }
     $accountCurrencyID = \CCrmCurrency::GetAccountCurrencyID();
     $sumData = \CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => $currencyID, 'SUM' => $sum));
     if (is_array($sumData)) {
         $sum = (double) $sumData['ACCOUNT_SUM'];
     }
     $latest = self::getLatest($ownerID);
     if (!is_array($latest)) {
         if ($semanticID === PhaseSemantics::SUCCESS) {
             //Creation of stub for successfully completed entity without invoices
             self::innerRegister(array('OWNER_ID' => $ownerID, 'CREATED_DATE' => new Date(), 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_SEMANTIC_ID' => PhaseSemantics::SUCCESS, 'STAGE_ID' => $stageID, 'IS_LOST' => 'N', 'CURRENCY_ID' => $accountCurrencyID, 'INVOICE_SUM' => 0.0, 'INVOICE_QTY' => 0, 'TOTAL_INVOICE_SUM' => 0.0, 'TOTAL_INVOICE_QTY' => 0, 'TOTAL_SUM' => $sum));
         }
         return true;
     }
     if ($startDate->getTimestamp() === $latest['START_DATE']->getTimestamp() && $endDate->getTimestamp() === $latest['END_DATE']->getTimestamp() && $responsibleID === (int) $latest['RESPONSIBLE_ID'] && $stageID === $latest['STAGE_ID'] && $semanticID === $latest['STAGE_SEMANTIC_ID'] && $sum === (double) $latest['TOTAL_SUM']) {
         return false;
     }
     if ($semanticID !== $latest['STAGE_SEMANTIC_ID'] && $latest['STAGE_SEMANTIC_ID'] === PhaseSemantics::SUCCESS && (int) $latest['INVOICE_QTY'] === 0) {
         //Clean up stub for successfully completed entity without invoices
         DealInvoiceStatisticsTable::delete(array('OWNER_ID' => $ownerID, 'CREATED_DATE' => $latest['CREATED_DATE']));
     } else {
         DealInvoiceStatisticsTable::synchronize($ownerID, array('START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_SEMANTIC_ID' => $semanticID, 'STAGE_ID' => $stageID, 'IS_LOST' => $isLost ? 'Y' : 'N', 'TOTAL_SUM' => $sum));
     }
     return true;
 }
예제 #6
0
 /**
  * @return void
  */
 public static function register($ownerID, array $entityFields = null)
 {
     if (!is_int($ownerID)) {
         $ownerID = (int) $ownerID;
     }
     if ($ownerID <= 0) {
         throw new Main\ArgumentException('Owner ID must be greater than zero.', 'ownerID');
     }
     if (!is_array($entityFields)) {
         $dbResult = \CCrmDeal::GetListEx(array(), array('=ID' => $ownerID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('STAGE_ID', 'ASSIGNED_BY_ID', 'BEGINDATE', 'CLOSEDATE', 'CURRENCY_ID', 'OPPORTUNITY', 'UF_*'));
         $entityFields = is_object($dbResult) ? $dbResult->Fetch() : null;
         if (!is_array($entityFields)) {
             return;
         }
     }
     $bindingMap = self::getSlotBindingMap();
     $stageID = isset($entityFields['STAGE_ID']) ? $entityFields['STAGE_ID'] : '';
     $semanticID = \CCrmDeal::GetSemanticID($stageID);
     $isLost = PhaseSemantics::isLost($semanticID);
     $isFinalized = PhaseSemantics::isFinal($semanticID);
     $responsibleID = isset($entityFields['ASSIGNED_BY_ID']) ? (int) $entityFields['ASSIGNED_BY_ID'] : 0;
     /** @var Date $startDate */
     $startDate = self::parseDateString(isset($entityFields['BEGINDATE']) ? $entityFields['BEGINDATE'] : '');
     if ($startDate === null || $startDate->getTimestamp() === false) {
         $startDate = isset($entityFields['DATE_CREATE']) ? self::parseDateString($entityFields['DATE_CREATE']) : null;
         if ($startDate === null || $startDate->getTimestamp() === false) {
             $startDate = new Date();
         }
     }
     /** @var Date $endDate */
     $endDate = self::parseDateString(isset($entityFields['CLOSEDATE']) ? $entityFields['CLOSEDATE'] : '');
     if ($endDate === null || $endDate->getTimestamp() === false) {
         $endDate = new Date('9999-12-31', 'Y-m-d');
     }
     $date = $isFinalized ? $endDate : $startDate;
     $day = (int) $date->format('d');
     $month = (int) $date->format('m');
     $quarter = $month <= 3 ? 1 : ($month <= 6 ? 2 : ($month <= 9 ? 3 : 4));
     $year = (int) $date->format('Y');
     $currencyID = isset($entityFields['CURRENCY_ID']) ? $entityFields['CURRENCY_ID'] : '';
     $accountingCurrencyID = \CCrmCurrency::GetAccountCurrencyID();
     $sum = isset($entityFields['OPPORTUNITY']) ? (double) $entityFields['OPPORTUNITY'] : 0.0;
     $binding = $bindingMap->get('SUM_TOTAL');
     if ($binding === null) {
         $total = isset($entityFields['OPPORTUNITY']) ? (double) $entityFields['OPPORTUNITY'] : 0.0;
     } else {
         $bindingFieldName = $binding->getFieldName();
         if ($bindingFieldName === '') {
             $bindingFieldName = 'OPPORTUNITY';
         }
         $total = isset($entityFields[$bindingFieldName]) ? (double) $entityFields[$bindingFieldName] : 0.0;
         if ($bindingFieldName !== 'OPPORTUNITY' && $binding->getOption('ADD_PRODUCT_ROW_SUM') === 'Y') {
             $total += $sum;
         }
     }
     if ($currencyID !== $accountingCurrencyID) {
         $accData = \CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => $currencyID, 'SUM' => $total, 'EXCH_RATE' => isset($entityFields['EXCH_RATE']) ? $entityFields['EXCH_RATE'] : null));
         if (is_array($accData)) {
             $total = (double) $accData['ACCOUNT_SUM'];
         }
     }
     $sumSlots = array();
     $sumSlotFields = DealSumStatisticsTable::getSumSlotFieldNames();
     foreach ($sumSlotFields as $fieldName) {
         $binding = $bindingMap->get($fieldName);
         if ($binding === null) {
             $slotSum = 0.0;
         } else {
             $bindingFieldName = $binding->getFieldName();
             $slotSum = $bindingFieldName !== '' && isset($entityFields[$bindingFieldName]) ? (double) $entityFields[$bindingFieldName] : 0.0;
             if ($binding->getOption('ADD_PRODUCT_ROW_SUM') === 'Y') {
                 $slotSum += $sum;
             }
         }
         if ($currencyID !== $accountingCurrencyID) {
             $accData = \CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => $currencyID, 'SUM' => $slotSum, 'EXCH_RATE' => isset($entityFields['EXCH_RATE']) ? $entityFields['EXCH_RATE'] : null));
             if (is_array($accData)) {
                 $slotSum = (double) $accData['ACCOUNT_SUM'];
             }
         }
         $sumSlots[$fieldName] = $slotSum;
     }
     $entities = self::getAll($ownerID);
     $final = null;
     $process = null;
     foreach ($entities as $entity) {
         if (PhaseSemantics::isFinal($entity['STAGE_SEMANTIC_ID'])) {
             $final = $entity;
         } else {
             $process = $entity;
         }
         if ($final && $process) {
             break;
         }
     }
     $latest = self::getLatest($ownerID);
     if (is_array($latest) && isset($latest['START_DATE']) && isset($latest['END_DATE'])) {
         if ($startDate->getTimestamp() === $latest['START_DATE']->getTimestamp() && $endDate->getTimestamp() === $latest['END_DATE']->getTimestamp() && $responsibleID === (int) $latest['RESPONSIBLE_ID'] && $stageID === $latest['STAGE_ID'] && $currencyID === $latest['CURRENCY_ID'] && $total === (double) $latest['SUM_TOTAL'] && $sumSlots['UF_SUM_1'] === (double) $latest['UF_SUM_1'] && $sumSlots['UF_SUM_2'] === (double) $latest['UF_SUM_2'] && $sumSlots['UF_SUM_3'] === (double) $latest['UF_SUM_3'] && $sumSlots['UF_SUM_4'] === (double) $latest['UF_SUM_4'] && $sumSlots['UF_SUM_5'] === (double) $latest['UF_SUM_5']) {
             return;
         }
         if ($startDate->getTimestamp() !== $latest['START_DATE']->getTimestamp() || $endDate->getTimestamp() !== $latest['END_DATE']->getTimestamp() || $responsibleID !== (int) $latest['RESPONSIBLE_ID']) {
             if (!$isFinalized) {
                 DealSumStatisticsTable::deleteByFilter(array('OWNER_ID' => $ownerID, 'SEMANTIC_ID' => PhaseSemantics::getFinalSemantis()));
                 DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $startDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getProcessSemantis());
             } else {
                 if ($startDate->getTimestamp() === $endDate->getTimestamp()) {
                     DealSumStatisticsTable::deleteByFilter(array('OWNER_ID' => $ownerID, 'SEMANTIC_ID' => PhaseSemantics::getProcessSemantis()));
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $endDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getFinalSemantis());
                 } else {
                     //Diphasic update of "final" semantics (first update with forged date: "1970-01-01") for avoid possible primary key conflict with "process" semantics
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => new Date('1970-01-01', 'Y-m-d'), 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getFinalSemantis());
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $startDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getProcessSemantis());
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $endDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getFinalSemantis());
                 }
             }
         }
     }
     $data = array_merge(array('OWNER_ID' => $ownerID, 'CREATED_DATE' => $date, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'PERIOD_YEAR' => $year, 'PERIOD_QUARTER' => $quarter, 'PERIOD_MONTH' => $month, 'PERIOD_DAY' => $day, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_SEMANTIC_ID' => $semanticID, 'STAGE_ID' => $stageID, 'IS_LOST' => $isLost ? 'Y' : 'N', 'CURRENCY_ID' => $accountingCurrencyID, 'SUM_TOTAL' => $total), $sumSlots);
     DealSumStatisticsTable::upsert($data);
 }