Example #1
0
 function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array())
 {
     $strHtml = '';
     $total = array();
     $arViewColumns =& $arResult['viewColumns'];
     $arData =& $arResult['data'];
     // static variables
     static $arGroups = array();
     static $arColumns = array();
     static $nGroups = 0;
     static $nColumns = 0;
     static $arValueTypes = array();
     static $marginWidth = 20;
     // initialize static variables
     if ($level === 0) {
         foreach ($arViewColumns as $viewColumnIndex => $viewColumn) {
             if ($viewColumn['grouping']) {
                 $arGroups[$nGroups++] = $viewColumnIndex;
             } else {
                 $arColumns[$nColumns++] = $viewColumnIndex;
             }
             $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn);
         }
     }
     $nRows = count($arRowSet);
     $bUseRowSet = $nRows > 0 ? true : false;
     if (!$bUseRowSet) {
         $nRows = count($arData);
     }
     if ($nGroups > 0) {
         // grouping table header
         if ($level === 0) {
             $bFirstGroup = true;
             $strHtml .= "\t" . '<table class="reports-grouping-table" cellpadding=2 cellspacing=0>' . PHP_EOL . "\t\t" . '<thead>' . PHP_EOL;
             foreach ($arGroups as $groupColumnIndex) {
                 $strHtml .= "\t\t\t" . '<tr class="reports-grouping-table-head-row">' . PHP_EOL . "\t\t\t\t" . '<td>' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']) . '</td>' . PHP_EOL;
                 if ($bFirstGroup) {
                     $bFirstGroup = false;
                     foreach ($arColumns as $viewColumnIndex) {
                         $strHtml .= "\t\t\t\t" . '<td style="text-align: center;"';
                         if ($nGroups > 1) {
                             $strHtml .= ' rowspan="' . htmlspecialcharsbx($nGroups) . '"';
                         }
                         $strHtml .= ' class="report-grouping-sort-column"';
                         $strHtml .= ' colId="' . $viewColumnIndex . '" defaultSort="' . $arViewColumns[$viewColumnIndex]['defaultSort'] . '">' . htmlspecialcharsbx($arViewColumns[$viewColumnIndex]['humanTitle']) . '</td>' . PHP_EOL;
                     }
                 }
                 $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL;
             }
             $strHtml .= "\t\t" . '</thead>' . PHP_EOL;
         }
         if ($nRows > 0) {
             // table header separator
             if ($level === 0) {
                 $strHtml .= "\t\t" . '<tbody>' . PHP_EOL . "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL;
             }
             // init total
             if ($nColumns > 0) {
                 foreach (array_keys($arColumns) as $columnIndex) {
                     $total[$columnIndex] = null;
                 }
             }
             if ($level < $nGroups) {
                 // fill group arrays
                 $arGroupValues = array();
                 $arGroupValuesIndexes = array();
                 $rowNumber = 0;
                 $groupDataType = $arValueTypes[$arGroups[$level]];
                 $dataIndex = null;
                 reset($arData);
                 while ($rowNumber++ < $nRows) {
                     // get index
                     if ($bUseRowSet) {
                         list(, $dataIndex) = each($arRowSet);
                     } else {
                         list($dataIndex, ) = each($arData);
                     }
                     // fill index and value of group
                     $arGroupValuesIndexes[] = $dataIndex;
                     $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']];
                     if ($groupDataType === 'date' || $groupDataType === 'datetime') {
                         $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT'));
                     }
                     // magic glue
                     if (is_array($groupValue)) {
                         $groupValue = join(' / ', $groupValue);
                     }
                     $arGroupValues[] = $groupValue;
                 }
                 // determine sort options
                 $groupSortOption = SORT_STRING;
                 $groupSortDirection = SORT_ASC;
                 if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) {
                     $groupSortOption = SORT_NUMERIC;
                 }
                 if ($arGroups[$level] == $arResult['sort_id']) {
                     if ($arResult['sort_type'] != 'ASC') {
                         $groupSortDirection = SORT_DESC;
                     }
                 }
                 // sort group
                 array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC);
                 // recursive scan
                 $prev = null;
                 $newRowSet = array();
                 $nGroupValues = count($arGroupValues);
                 $nSubRows = 0;
                 for ($i = 0; $i < $nGroupValues; $i++) {
                     $cur = $arGroupValues[$i];
                     if ($i == 0) {
                         $prev = $cur;
                     }
                     $bLastValue = $nGroupValues - 1 == $i;
                     if ($cur != $prev || $bLastValue) {
                         $n = $bLastValue && $cur != $prev ? 2 : 1;
                         while ($n-- > 0) {
                             if ($bLastValue && $cur == $prev) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet);
                             $arSubTotal = $arGroupingResult['total'];
                             $strSubHtml = $arGroupingResult['html'];
                             unset($arGroupingResult);
                             $newRowSet = array();
                             if (!$bLastValue) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $prev = $cur;
                             // show row
                             $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1;
                             $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName'];
                             $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey];
                             // magic glue
                             if (is_array($groupValue)) {
                                 $groupValue = join(' / ', $groupValue);
                             }
                             if ($level == $nGroups - 1) {
                                 $rowClass = ' reports-grouping-data-row';
                             } else {
                                 $rowClass = ' reports-grouping-group-row';
                             }
                             if (!empty($rowClass)) {
                                 $rowClass = ' class="' . ltrim($rowClass) . '"';
                             }
                             $margin = $level > 0 ? ' style="margin-left: ' . $level * $marginWidth . 'px;"' : '';
                             /*$rowClass .= ' style="mso-outline-level:'.($level+1).'"';*/
                             $strHtml .= "\t\t\t" . '<tr' . $rowClass . '>' . PHP_EOL . "\t\t\t\t" . '<td><div' . $margin . '>' . $groupValue . '</div></td>' . PHP_EOL;
                             foreach ($arSubTotal as $k => $subValue) {
                                 $cellStyle = '';
                                 if ($arResult['settings']['red_neg_vals'] === true) {
                                     if (is_numeric($subValue) && $subValue < 0) {
                                         $cellStyle .= ' color: red;';
                                     }
                                 }
                                 // cell align
                                 $colAlign = $arViewColumns[$arColumns[$k]]['align'];
                                 if ($colAlign === null) {
                                     if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]])) {
                                         $cellStyle .= ' text-align: right;';
                                     }
                                 } else {
                                     if ($colAlign === 'right') {
                                         $cellStyle .= ' text-align: right;';
                                     }
                                 }
                                 if (!empty($cellStyle)) {
                                     $cellStyle = ' style="' . ltrim($cellStyle) . '"';
                                 }
                                 $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                                 if ($bGroupingSubtotal || $level == $nGroups - 1) {
                                     $finalSubValue = $subValue;
                                     if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) {
                                         // format subtotal value
                                         $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                         call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                                     }
                                 } else {
                                     $finalSubValue = '&nbsp;';
                                 }
                                 $strHtml .= "\t\t\t\t" . '<td' . $cellStyle . '>' . $finalSubValue . '</td>' . PHP_EOL;
                             }
                             $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL;
                             $strHtml .= $strSubHtml;
                             // total += subtotal
                             if ($nColumns > 0) {
                                 foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                                     $columnDataType = $arValueTypes[$viewColumnIndex];
                                     if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                         if (is_string($arSubTotal[$columnIndex])) {
                                             $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]);
                                         }
                                         $total[$columnIndex] += $arSubTotal[$columnIndex];
                                     }
                                 }
                                 $nSubRows++;
                             }
                         }
                         // while ($n-- > 0)
                     } else {
                         $newRowSet[] = $arGroupValuesIndexes[$i];
                     }
                 }
                 // calculate average values
                 if ($nSubRows > 1) {
                     foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                         if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                             $total[$columnIndex] = $total[$columnIndex] / $nSubRows;
                         }
                     }
                 }
             } else {
                 if ($nColumns > 0) {
                     $rowNumber = 0;
                     while ($rowNumber++ < $nRows) {
                         // get index
                         if ($bUseRowSet) {
                             list(, $dataIndex) = each($arRowSet);
                         } else {
                             list($dataIndex, ) = each($arData);
                         }
                         // total += values
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             $columnDataType = $arValueTypes[$viewColumnIndex];
                             if ($nRows == 1) {
                                 $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName'];
                                 $dataValue = $arData[$dataIndex][$dataValueKey];
                                 if ($columnDataType === 'float' && is_string($dataValue)) {
                                     $dataValue = str_replace(' ', '', $dataValue);
                                 }
                                 $total[$columnIndex] = $dataValue;
                             } else {
                                 if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                     $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']];
                                     if (is_string($dataValue)) {
                                         $dataValue = str_replace(' ', '', $dataValue);
                                     }
                                     $total[$columnIndex] += $dataValue;
                                 }
                             }
                         }
                     }
                     // calculate average values
                     if ($nRows > 1) {
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                                 $total[$columnIndex] = $total[$columnIndex] / $nRows;
                             }
                         }
                     }
                 }
             }
         }
         // show total
         if ($level === 0) {
             if (count($total) > 0) {
                 // show total check
                 $bShowTotal = false;
                 foreach ($total as $k => $v) {
                     if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) {
                         $bShowTotal = true;
                         break;
                     }
                 }
                 if ($bShowTotal) {
                     $strHtml .= "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL;
                     $strHtml .= "\t\t\t" . '<tr class="reports-grouping-total-row">' . PHP_EOL . "\t\t\t\t" . '<td>' . htmlspecialcharsbx(GetMessage('REPORT_TOTAL')) . '</td>' . PHP_EOL;
                     foreach ($total as $k => $v) {
                         $cellStyle = '';
                         if ($arResult['settings']['red_neg_vals'] === true) {
                             if (is_numeric($v) && $v < 0) {
                                 $cellStyle .= ' color: red;';
                             }
                         }
                         // cell align
                         $colAlign = $arViewColumns[$arColumns[$k]]['align'];
                         if ($colAlign === null) {
                             if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]])) {
                                 $cellStyle = ' text-align: right;';
                             }
                         } else {
                             if ($colAlign === 'right') {
                                 $cellStyle = ' text-align: right;';
                             }
                         }
                         $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                         if ($bGroupingSubtotal) {
                             $finalTotalValue = $v;
                             if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) {
                                 // format subtotal value
                                 $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                 call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                             }
                         } else {
                             $finalTotalValue = '&nbsp;';
                         }
                         if (!empty($cellStyle)) {
                             $cellStyle = ' class="' . ltrim($cellStyle) . '"';
                         }
                         $strHtml .= "\t\t\t\t" . '<td' . $cellStyle . '>' . $finalTotalValue . '</td>' . PHP_EOL;
                     }
                     $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL;
                 }
             }
             $strHtml .= "\t\t" . '</tbody>' . PHP_EOL . "\t" . '</table>' . PHP_EOL;
         }
     }
     return array('total' => $total, 'html' => $strHtml);
 }
Example #2
0
 function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array())
 {
     $arReportData = array();
     $total = array();
     $arViewColumns =& $arResult['viewColumns'];
     $arData =& $arResult['data'];
     $finalRow = 0;
     $headerHtml = '';
     // static variables
     static $arGroups = array();
     static $arColumns = array();
     static $nGroups = 0;
     static $nColumns = 0;
     static $arValueTypes = array();
     // initialize static variables
     if ($level === 0) {
         foreach ($arViewColumns as $viewColumnIndex => $viewColumn) {
             if ($viewColumn['grouping']) {
                 $arGroups[$nGroups++] = $viewColumnIndex;
             } else {
                 $arColumns[$nColumns++] = $viewColumnIndex;
             }
             $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn, $arResult['customColumnTypes']);
         }
         $headerHtml = getReportHeader($arGroups, $arResult);
     }
     $nRows = count($arRowSet);
     $bUseRowSet = $nRows > 0 ? true : false;
     if (!$bUseRowSet) {
         $nRows = count($arData);
     }
     if ($nGroups > 0) {
         if ($nRows > 0) {
             // init total
             if ($nColumns > 0) {
                 foreach (array_keys($arColumns) as $columnIndex) {
                     $total[$columnIndex] = null;
                 }
             }
             if ($level < $nGroups) {
                 // fill group arrays
                 $arGroupValues = array();
                 $arGroupValuesIndexes = array();
                 $rowNumber = 0;
                 $groupDataType = $arValueTypes[$arGroups[$level]];
                 $dataIndex = null;
                 reset($arData);
                 while ($rowNumber++ < $nRows) {
                     // get index
                     if ($bUseRowSet) {
                         list(, $dataIndex) = each($arRowSet);
                     } else {
                         list($dataIndex, ) = each($arData);
                     }
                     // fill index and value of group
                     $arGroupValuesIndexes[] = $dataIndex;
                     $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']];
                     if ($groupDataType === 'date' || $groupDataType === 'datetime') {
                         $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT'));
                     }
                     // magic glue
                     if (is_array($groupValue)) {
                         $groupValue = join(' / ', $groupValue);
                     }
                     $arGroupValues[] = $groupValue;
                 }
                 // determine sort options
                 $groupSortOption = SORT_STRING;
                 $groupSortDirection = SORT_ASC;
                 if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) {
                     $groupSortOption = SORT_NUMERIC;
                 }
                 if ($arGroups[$level] == $arResult['sort_id']) {
                     if ($arResult['sort_type'] != 'ASC') {
                         $groupSortDirection = SORT_DESC;
                     }
                 }
                 // sort group
                 array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC);
                 // recursive scan
                 $prev = null;
                 $newRowSet = array();
                 $nGroupValues = count($arGroupValues);
                 $nSubRows = 0;
                 $closeTBody = false;
                 for ($i = 0; $i < $nGroupValues; $i++) {
                     $cur = $arGroupValues[$i];
                     if ($i == 0) {
                         $prev = $cur;
                     }
                     $bLastValue = $nGroupValues - 1 == $i;
                     if ($cur != $prev || $bLastValue) {
                         $n = $bLastValue && $cur != $prev ? 2 : 1;
                         while ($n-- > 0) {
                             $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1;
                             if ($bLastValue && $cur == $prev) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet);
                             $arSubTotal = $arGroupingResult['total'];
                             $arReportData[$groupValueIndex]["CLOSED"] = true;
                             if (!empty($arGroupingResult['array'])) {
                                 $arReportData[$groupValueIndex]["SECTIONS"] = $arGroupingResult['array'];
                             }
                             unset($arGroupingResult);
                             $newRowSet = array();
                             if (!$bLastValue) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $prev = $cur;
                             // show row
                             $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName'];
                             $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey];
                             // magic glue
                             if (is_array($groupValue)) {
                                 $groupValue = join(' / ', $groupValue);
                             }
                             if ($level == 0) {
                                 $closeTBody = true;
                                 $rowClass = ' class="mobile-admin-report-category"';
                             } else {
                                 $rowClass = '';
                             }
                             foreach ($arSubTotal as $k => $subValue) {
                                 $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                                 if ($bGroupingSubtotal || $level == $nGroups - 1) {
                                     $finalSubValue = $subValue;
                                     if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) {
                                         // format subtotal value
                                         $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                         call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                                     }
                                 } else {
                                     $finalSubValue = '&nbsp;';
                                 }
                                 if ($k == 0) {
                                     $arReportData[$groupValueIndex]["TITLE"] = $groupValue;
                                 }
                                 if (empty($arReportData[$groupValueIndex]["SECTIONS"])) {
                                     $arReportData[$groupValueIndex]["CONTENT"][$k]["TITLE"] = $arViewColumns[$arColumns[$k]]['humanTitle'] . ": ";
                                     $arReportData[$groupValueIndex]["CONTENT"][$k]["VALUE"] = $finalSubValue;
                                 }
                             }
                             // total += subtotal
                             if ($nColumns > 0) {
                                 foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                                     $columnDataType = $arValueTypes[$viewColumnIndex];
                                     if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                         if (is_string($arSubTotal[$columnIndex])) {
                                             $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]);
                                         }
                                         $total[$columnIndex] += $arSubTotal[$columnIndex];
                                     }
                                 }
                                 $nSubRows++;
                             }
                         }
                         // while ($n-- > 0)
                     } else {
                         $newRowSet[] = $arGroupValuesIndexes[$i];
                     }
                     $finalRow = $i;
                 }
                 // calculate average values
                 if ($nSubRows > 1) {
                     foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                         if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                             $total[$columnIndex] = $total[$columnIndex] / $nSubRows;
                         }
                     }
                 }
             } else {
                 if ($nColumns > 0) {
                     $rowNumber = 0;
                     while ($rowNumber++ < $nRows) {
                         // get index
                         if ($bUseRowSet) {
                             list(, $dataIndex) = each($arRowSet);
                         } else {
                             list($dataIndex, ) = each($arData);
                         }
                         // total += values
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             $columnDataType = $arValueTypes[$viewColumnIndex];
                             if ($nRows == 1) {
                                 $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName'];
                                 $dataValue = $arData[$dataIndex][$dataValueKey];
                                 if ($columnDataType === 'integer' || $columnDataType === 'float' && is_string($dataValue)) {
                                     $dataValue = str_replace(' ', '', $dataValue);
                                 }
                                 // normal value
                                 $total[$columnIndex] = $dataValue;
                             } else {
                                 if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                     $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']];
                                     if (is_string($dataValue)) {
                                         $dataValue = str_replace(' ', '', $dataValue);
                                     }
                                     $total[$columnIndex] += $dataValue;
                                 }
                             }
                         }
                     }
                     // calculate average values
                     if ($nRows > 1) {
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                                 $total[$columnIndex] = $total[$columnIndex] / $nRows;
                             }
                         }
                     }
                 }
             }
         }
         // show total
         if ($level === 0) {
             if (count($total) > 0) {
                 // show total check
                 $bShowTotal = false;
                 foreach ($total as $k => $v) {
                     if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) {
                         $bShowTotal = true;
                         break;
                     }
                 }
                 if ($bShowTotal) {
                     $arReportData[$finalRow + 1]["TITLE"] = GetMessage('REPORT_TOTAL');
                     $arReportData[$finalRow + 1]["CLOSED"] = true;
                     $arReportData[$finalRow + 1]["HIGHLIGHTED"] = true;
                     foreach ($total as $k => $v) {
                         $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                         if ($bGroupingSubtotal) {
                             $finalTotalValue = $v;
                             if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) {
                                 // format subtotal value
                                 $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                 call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                             }
                         } else {
                             $finalTotalValue = '&nbsp;';
                         }
                         $arReportData[$finalRow + 1]["CONTENT"][$k]["TITLE"] = $arViewColumns[$arColumns[$k]]['humanTitle'] . ": ";
                         $arReportData[$finalRow + 1]["CONTENT"][$k]["VALUE"] = $finalTotalValue;
                         //$arReportData["finalTotalValue"][$k] = $finalTotalValue;
                     }
                 }
             }
         }
     }
     return array('total' => $total, 'array' => $arReportData, 'headerHtml' => $headerHtml);
 }
Example #3
0
 function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array())
 {
     $strHtml = '';
     $total = array();
     $arViewColumns =& $arResult['viewColumns'];
     $arData =& $arResult['data'];
     // static variables
     static $arGroups = array();
     static $arColumns = array();
     static $nGroups = 0;
     static $nColumns = 0;
     static $arValueTypes = array();
     // initialize static variables
     if ($level === 0) {
         foreach ($arViewColumns as $viewColumnIndex => $viewColumn) {
             if ($viewColumn['grouping']) {
                 $arGroups[$nGroups++] = $viewColumnIndex;
             } else {
                 $arColumns[$nColumns++] = $viewColumnIndex;
             }
             $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn, $arResult['customColumnTypes']);
         }
     }
     $nRows = count($arRowSet);
     $bUseRowSet = $nRows > 0 ? true : false;
     if (!$bUseRowSet) {
         $nRows = count($arData);
     }
     if ($nGroups > 0) {
         // grouping table header
         if ($level === 0) {
             $strHtml .= "\t" . '<div class="order_infoblock">' . PHP_EOL . "\t\t" . '<div class="order_infoblock_content">' . PHP_EOL . "\t\t\t" . '<table class="bx_table_item_remainder">' . PHP_EOL . "\t\t\t\t" . '<thead>' . PHP_EOL;
             $strHtml .= "\t\t\t\t\t" . '<tr class="mobile-admin-report-header">' . PHP_EOL . "\t\t\t\t\t\t" . '<td>' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']);
             $bFirst = true;
             foreach ($arGroups as $groupColumnIndex) {
                 if ($bFirst) {
                     $strHtml .= htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']);
                 } else {
                     $strHtml .= '<span>' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']) . '</span>';
                 }
                 $bFirst = false;
             }
             $strHtml .= "\t\t\t\t\t\t" . '</td>' . PHP_EOL;
             foreach ($arColumns as $viewColumnIndex) {
                 $strHtml .= "\t\t\t\t\t\t" . '<td defaultSort="' . $arViewColumns[$viewColumnIndex]['defaultSort'] . '">' . htmlspecialcharsbx($arViewColumns[$viewColumnIndex]['humanTitle']) . "\t\t\t\t\t\t" . '</td>' . PHP_EOL;
             }
             $strHtml .= "\t\t\t\t\t" . '</tr>' . PHP_EOL;
             $strHtml .= "\t\t\t\t" . '</thead>' . PHP_EOL;
         }
         if ($nRows > 0) {
             // init total
             if ($nColumns > 0) {
                 foreach (array_keys($arColumns) as $columnIndex) {
                     $total[$columnIndex] = null;
                 }
             }
             if ($level < $nGroups) {
                 // fill group arrays
                 $arGroupValues = array();
                 $arGroupValuesIndexes = array();
                 $rowNumber = 0;
                 $groupDataType = $arValueTypes[$arGroups[$level]];
                 $dataIndex = null;
                 reset($arData);
                 while ($rowNumber++ < $nRows) {
                     // get index
                     if ($bUseRowSet) {
                         list(, $dataIndex) = each($arRowSet);
                     } else {
                         list($dataIndex, ) = each($arData);
                     }
                     // fill index and value of group
                     $arGroupValuesIndexes[] = $dataIndex;
                     $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']];
                     if ($groupDataType === 'date' || $groupDataType === 'datetime') {
                         $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT'));
                     }
                     // magic glue
                     if (is_array($groupValue)) {
                         $groupValue = join(' / ', $groupValue);
                     }
                     $arGroupValues[] = $groupValue;
                 }
                 // determine sort options
                 $groupSortOption = SORT_STRING;
                 $groupSortDirection = SORT_ASC;
                 if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) {
                     $groupSortOption = SORT_NUMERIC;
                 }
                 if ($arGroups[$level] == $arResult['sort_id']) {
                     if ($arResult['sort_type'] != 'ASC') {
                         $groupSortDirection = SORT_DESC;
                     }
                 }
                 // sort group
                 array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC);
                 // recursive scan
                 $prev = null;
                 $newRowSet = array();
                 $nGroupValues = count($arGroupValues);
                 $nSubRows = 0;
                 $closeTBody = false;
                 for ($i = 0; $i < $nGroupValues; $i++) {
                     $cur = $arGroupValues[$i];
                     if ($i == 0) {
                         $prev = $cur;
                     }
                     $bLastValue = $nGroupValues - 1 == $i;
                     if ($cur != $prev || $bLastValue) {
                         $n = $bLastValue && $cur != $prev ? 2 : 1;
                         while ($n-- > 0) {
                             if ($bLastValue && $cur == $prev) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet);
                             $arSubTotal = $arGroupingResult['total'];
                             $strSubHtml = $arGroupingResult['html'];
                             unset($arGroupingResult);
                             $newRowSet = array();
                             if (!$bLastValue) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $prev = $cur;
                             // show row
                             $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1;
                             $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName'];
                             $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey];
                             // magic glue
                             if (is_array($groupValue)) {
                                 $groupValue = join(' / ', $groupValue);
                             }
                             if ($level == 0) {
                                 if ($closeTBody) {
                                     $strHtml .= "\t\t\t\t" . '</tbody>' . PHP_EOL;
                                 }
                                 $strHtml .= "\t\t\t\t" . '<tbody>' . PHP_EOL;
                                 $closeTBody = true;
                                 $rowClass = ' class="mobile-admin-report-category"';
                             } else {
                                 $rowClass = '';
                             }
                             $strHtml .= "\t\t\t\t\t" . '<tr' . $rowClass . '>' . PHP_EOL . "\t\t\t\t\t\t" . '<td>';
                             if ($level == $nGroups - 1) {
                                 $strHtml .= '<span>' . $groupValue . '</span>';
                             } else {
                                 $strHtml .= $groupValue;
                             }
                             $strHtml .= "\t\t\t\t\t\t" . '</td>' . PHP_EOL;
                             foreach ($arSubTotal as $k => $subValue) {
                                 $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                                 if ($bGroupingSubtotal || $level == $nGroups - 1) {
                                     $finalSubValue = $subValue;
                                     if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) {
                                         // format subtotal value
                                         $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                         call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                                     }
                                 } else {
                                     $finalSubValue = '&nbsp;';
                                 }
                                 $strHtml .= "\t\t\t\t\t\t" . '<td>' . $finalSubValue . '</td>' . PHP_EOL;
                             }
                             $strHtml .= "\t\t\t\t\t" . '</tr>' . PHP_EOL;
                             $strHtml .= $strSubHtml;
                             // total += subtotal
                             if ($nColumns > 0) {
                                 foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                                     $columnDataType = $arValueTypes[$viewColumnIndex];
                                     if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                         if (is_string($arSubTotal[$columnIndex])) {
                                             $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]);
                                         }
                                         $total[$columnIndex] += $arSubTotal[$columnIndex];
                                     }
                                 }
                                 $nSubRows++;
                             }
                         }
                         // while ($n-- > 0)
                     } else {
                         $newRowSet[] = $arGroupValuesIndexes[$i];
                     }
                 }
                 // calculate average values
                 if ($nSubRows > 1) {
                     foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                         if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                             $total[$columnIndex] = $total[$columnIndex] / $nSubRows;
                         }
                     }
                 }
             } else {
                 if ($nColumns > 0) {
                     $rowNumber = 0;
                     while ($rowNumber++ < $nRows) {
                         // get index
                         if ($bUseRowSet) {
                             list(, $dataIndex) = each($arRowSet);
                         } else {
                             list($dataIndex, ) = each($arData);
                         }
                         // total += values
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             $columnDataType = $arValueTypes[$viewColumnIndex];
                             if ($nRows == 1) {
                                 $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName'];
                                 $dataValue = $arData[$dataIndex][$dataValueKey];
                                 if ($columnDataType === 'integer' || $columnDataType === 'float' && is_string($dataValue)) {
                                     $dataValue = str_replace(' ', '', $dataValue);
                                 }
                                 // normal value
                                 $total[$columnIndex] = $dataValue;
                             } else {
                                 if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                     $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']];
                                     if (is_string($dataValue)) {
                                         $dataValue = str_replace(' ', '', $dataValue);
                                     }
                                     $total[$columnIndex] += $dataValue;
                                 }
                             }
                         }
                     }
                     // calculate average values
                     if ($nRows > 1) {
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                                 $total[$columnIndex] = $total[$columnIndex] / $nRows;
                             }
                         }
                     }
                 }
             }
         }
         // show total
         if ($level === 0) {
             if (count($total) > 0) {
                 // show total check
                 $bShowTotal = false;
                 foreach ($total as $k => $v) {
                     if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) {
                         $bShowTotal = true;
                         break;
                     }
                 }
                 if ($bShowTotal) {
                     $strHtml .= "\t\t\t" . '</tbody><tbody><tr style="background: none repeat scroll 0 0 #EDF2D4;">' . PHP_EOL . "\t\t\t\t" . '<td>' . htmlspecialcharsbx(GetMessage('REPORT_TOTAL')) . ':</td>' . PHP_EOL;
                     foreach ($total as $k => $v) {
                         $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                         if ($bGroupingSubtotal) {
                             $finalTotalValue = $v;
                             if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) {
                                 // format subtotal value
                                 $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                 call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                             }
                         } else {
                             $finalTotalValue = '&nbsp;';
                         }
                         $strHtml .= "\t\t\t\t" . '<td>' . $finalTotalValue . '</td>' . PHP_EOL;
                     }
                     $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL;
                 }
             }
             $strHtml .= "\t" . '</tbody></table>' . PHP_EOL . '</div></div>' . PHP_EOL;
         }
     }
     return array('total' => $total, 'html' => $strHtml);
 }
Example #4
0
 function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array())
 {
     $strHtml = '';
     $total = array();
     $arViewColumns =& $arResult['viewColumns'];
     $arData =& $arResult['data'];
     // static variables
     static $arGroups = array();
     static $arColumns = array();
     static $nGroups = 0;
     static $nColumns = 0;
     static $arValueTypes = array();
     static $marginWidth = 20;
     // chart info variables
     static $bChartGrouping = false;
     static $arChartColumns = array();
     static $chartColumnMaxGroupLevel = -1;
     static $chartDataRowIndex = -1;
     static $arChartGroupingValues = array();
     // initialize static variables
     if ($level === 0) {
         foreach ($arViewColumns as $viewColumnIndex => $viewColumn) {
             if ($viewColumn['grouping']) {
                 $arGroups[$nGroups++] = $viewColumnIndex;
             } else {
                 $arColumns[$nColumns++] = $viewColumnIndex;
             }
             $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn, $arResult['customColumnTypes'], $arResult['helperClassName']);
         }
         // chart columns
         if ($arParams['USE_CHART'] && $arResult['settings']['chart']['display']) {
             $chartSettings = $arResult['settings']['chart'];
             if (isset($chartSettings['x_column']) && is_array($chartSettings['y_columns'])) {
                 $arChartColumns[] = $chartSettings['x_column'];
                 $arChartColumns = array_merge($arChartColumns, $chartSettings['y_columns']);
             }
             // obtain max group level of chart columns
             foreach ($arChartColumns as $nChartColumn) {
                 foreach ($arGroups as $groupLevel => $nGroup) {
                     if ($nChartColumn == $nGroup) {
                         $bChartGrouping = true;
                         $chartColumnMaxGroupLevel = max($chartColumnMaxGroupLevel, $groupLevel);
                     }
                 }
             }
         }
     }
     $nRows = count($arRowSet);
     $bUseRowSet = $nRows > 0 ? true : false;
     if (!$bUseRowSet) {
         $nRows = count($arData);
     }
     if ($nGroups > 0) {
         // grouping table header
         if ($level === 0) {
             $bFirstGroup = true;
             $strHtml .= '<div class="reports-grouping-table-wrap">' . PHP_EOL . "\t" . '<table id="report-result-table" class="reports-grouping-table" cellpadding=2 cellspacing=0>' . PHP_EOL . "\t\t" . '<thead>' . PHP_EOL;
             foreach ($arGroups as $groupColumnIndex) {
                 $strHtml .= "\t\t\t" . '<tr class="adm-list-table-header reports-grouping-table-head-row">' . PHP_EOL . "\t\t\t\t" . '<td class="adm-list-table-cell">' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']) . '</td>' . PHP_EOL;
                 if ($bFirstGroup) {
                     $bFirstGroup = false;
                     foreach ($arColumns as $viewColumnIndex) {
                         $strHtml .= "\t\t\t\t" . '<td class="adm-list-table-cell align-center"';
                         if ($nGroups > 1) {
                             $strHtml .= ' rowspan="' . htmlspecialcharsbx($nGroups) . '"';
                         }
                         $strHtml .= ' colId="' . $viewColumnIndex . '" defaultSort="' . $arViewColumns[$viewColumnIndex]['defaultSort'] . '">' . htmlspecialcharsbx($arViewColumns[$viewColumnIndex]['humanTitle']) . '</td>' . PHP_EOL;
                     }
                 }
                 $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL;
             }
             $strHtml .= "\t\t" . '</thead>' . PHP_EOL;
         }
         if ($nRows > 0) {
             // table header separator
             if ($level === 0) {
                 $strHtml .= "\t\t" . '<tbody>' . PHP_EOL . "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL;
             }
             // init total
             if ($nColumns > 0) {
                 foreach (array_keys($arColumns) as $columnIndex) {
                     $total[$columnIndex] = null;
                 }
             }
             if ($level < $nGroups) {
                 // fill group arrays
                 $arGroupValues = array();
                 $arGroupValuesIndexes = array();
                 $rowNumber = 0;
                 $groupDataType = $arValueTypes[$arGroups[$level]];
                 $dataIndex = null;
                 reset($arData);
                 while ($rowNumber++ < $nRows) {
                     // get index
                     if ($bUseRowSet) {
                         list(, $dataIndex) = each($arRowSet);
                     } else {
                         list($dataIndex, ) = each($arData);
                     }
                     // fill index and value of group
                     $arGroupValuesIndexes[] = $dataIndex;
                     $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']];
                     if ($groupDataType === 'date' || $groupDataType === 'datetime') {
                         $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT'));
                     }
                     // magic glue
                     if (is_array($groupValue)) {
                         $groupValue = join(' / ', $groupValue);
                     }
                     $arGroupValues[] = $groupValue;
                 }
                 // determine sort options
                 $groupSortOption = SORT_STRING;
                 $groupSortDirection = SORT_ASC;
                 if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) {
                     $groupSortOption = SORT_NUMERIC;
                 }
                 if ($arGroups[$level] == $arResult['sort_id']) {
                     if ($arResult['sort_type'] != 'ASC') {
                         $groupSortDirection = SORT_DESC;
                     }
                 }
                 // sort group
                 array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC);
                 // recursive scan
                 $prev = null;
                 $newRowSet = array();
                 $nGroupValues = count($arGroupValues);
                 $nSubRows = 0;
                 for ($i = 0; $i < $nGroupValues; $i++) {
                     $cur = $arGroupValues[$i];
                     if ($i == 0) {
                         $prev = $cur;
                     }
                     $bLastValue = $nGroupValues - 1 == $i;
                     if ($cur != $prev || $bLastValue) {
                         $n = $bLastValue && $cur != $prev ? 2 : 1;
                         while ($n-- > 0) {
                             // chart values index
                             if ($bChartGrouping && $level == $chartColumnMaxGroupLevel) {
                                 $chartDataRowIndex++;
                             }
                             if ($bLastValue && $cur == $prev) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet);
                             $arSubTotal = $arGroupingResult['total'];
                             $strSubHtml = $arGroupingResult['html'];
                             unset($arGroupingResult);
                             $newRowSet = array();
                             if (!$bLastValue) {
                                 $newRowSet[] = $arGroupValuesIndexes[$i];
                             }
                             $prev = $cur;
                             // show row
                             $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1;
                             $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName'];
                             $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey];
                             // magic glue
                             if (is_array($groupValue)) {
                                 $groupValue = join(' / ', $groupValue);
                             }
                             // add chart values
                             if ($bChartGrouping && in_array($arGroups[$level], $arChartColumns)) {
                                 $tempChartDataRowIndex = $chartDataRowIndex;
                                 while ($tempChartDataRowIndex >= 0 && !isset($arChartGroupingValues[$tempChartDataRowIndex][$arGroups[$level]])) {
                                     $arChartGroupingValues[$tempChartDataRowIndex--][$arGroups[$level]] = $groupValue;
                                 }
                                 unset($tempChartDataRowIndex);
                             }
                             // values of groups were processed as normal values
                             /*if (method_exists($arResult['helperClassName'], 'formatResultGroupingValue'))
                             		{
                             			// format group value
                             			call_user_func(
                             				array($arResult['helperClassName'], 'formatResultGroupingValue'),
                             				array(
                             					'k' => $groupValueKey,
                             					'v' => &$groupValue,
                             					'row' => &$arData[$arGroupValuesIndexes[$groupValueIndex]],
                             					'cInfo' => &$arViewColumns[$arGroups[$level]]
                             				)
                             			);
                             		}*/
                             $cellClassFirstColumn = '';
                             if ($level == $nGroups - 1) {
                                 $rowClass = ' reports-grouping-data-row';
                             } else {
                                 $rowClass = ' reports-grouping-group-row';
                                 $cellClassFirstColumn = 'adm-list-table-cell';
                             }
                             $cellClassAttr = '';
                             if (!empty($cellClassFirstColumn)) {
                                 $cellClassAttr = ' class="' . $cellClassFirstColumn . '"';
                             }
                             $margin = $level > 0 ? ' style="margin-left: ' . $level * $marginWidth . 'px;"' : '';
                             $strHtml .= "\t\t\t" . '<tr class="adm-list-table-header' . $rowClass . '">' . PHP_EOL . "\t\t\t\t" . '<td' . $cellClassAttr . '><div' . $margin . '>' . ($groupValue === '' ? '&nbsp;' : $groupValue) . '</div></td>' . PHP_EOL;
                             foreach ($arSubTotal as $k => $subValue) {
                                 $cellAlign = '';
                                 $cellClass = $cellClassFirstColumn;
                                 if ($arResult['settings']['red_neg_vals'] === true) {
                                     if (is_numeric($subValue) && $subValue < 0) {
                                         $cellClass .= ' report-red-neg-val';
                                     }
                                 }
                                 // cell align
                                 $colAlign = $arViewColumns[$arColumns[$k]]['align'];
                                 if ($colAlign === null) {
                                     if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]], $arResult['helperClassName'])) {
                                         $cellAlign = ' align-right';
                                     }
                                 } else {
                                     if ($colAlign === 'right') {
                                         $cellAlign = ' align-right"';
                                     }
                                 }
                                 if (!empty($cellAlign)) {
                                     $cellClass .= $cellAlign;
                                 }
                                 if (!empty($cellClass)) {
                                     $cellClass = ' class="' . ltrim($cellClass) . '"';
                                 }
                                 $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                                 if ($bGroupingSubtotal || $level == $nGroups - 1) {
                                     $finalSubValue = $subValue;
                                     if (method_exists($arResult['helperClassName'], 'formatResultGroupingTotal')) {
                                         // format subtotal value
                                         $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                         call_user_func(array($arResult['helperClassName'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                                     }
                                 } else {
                                     $finalSubValue = '';
                                 }
                                 $strHtml .= "\t\t\t\t" . '<td' . $cellClass . '>' . ($finalSubValue === '' ? '&nbsp;' : $finalSubValue) . '</td>' . PHP_EOL;
                                 // add chart values
                                 if ($bChartGrouping && $level == $chartColumnMaxGroupLevel && in_array($arColumns[$k], $arChartColumns)) {
                                     $arChartGroupingValues[$chartDataRowIndex][$arColumns[$k]] = $finalSubValue;
                                 }
                             }
                             $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL;
                             $strHtml .= $strSubHtml;
                             // total += subtotal
                             if ($nColumns > 0) {
                                 foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                                     $columnDataType = $arValueTypes[$viewColumnIndex];
                                     if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                         if (is_string($arSubTotal[$columnIndex])) {
                                             $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]);
                                         }
                                         $total[$columnIndex] += $arSubTotal[$columnIndex];
                                     }
                                 }
                                 $nSubRows++;
                             }
                         }
                         // while ($n-- > 0)
                     } else {
                         $newRowSet[] = $arGroupValuesIndexes[$i];
                     }
                 }
                 // calculate average values
                 if ($nSubRows > 1) {
                     foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                         if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                             $total[$columnIndex] = $total[$columnIndex] / $nSubRows;
                         }
                     }
                 }
             } else {
                 if ($nColumns > 0) {
                     $rowNumber = 0;
                     while ($rowNumber++ < $nRows) {
                         // get index
                         if ($bUseRowSet) {
                             list(, $dataIndex) = each($arRowSet);
                         } else {
                             list($dataIndex, ) = each($arData);
                         }
                         // total += values
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             $columnDataType = $arValueTypes[$viewColumnIndex];
                             if ($nRows == 1) {
                                 $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName'];
                                 $dataValue = $arData[$dataIndex][$dataValueKey];
                                 // normal value
                                 /*if (method_exists($arResult['helperClassName'], 'formatResultGroupingValue'))
                                 		{
                                 			// format result value
                                 			call_user_func(
                                 				array($arResult['helperClassName'], 'formatResultGroupingValue'),
                                 				array(
                                 					'k' => $dataValueKey,
                                 					'v' => &$dataValue,
                                 					'row' => &$arData[$dataIndex],
                                 					'cInfo' => &$arViewColumns[$viewColumnIndex]
                                 				)
                                 			);
                                 		}*/
                                 if ($columnDataType === 'integer' || $columnDataType === 'float' && is_string($dataValue)) {
                                     $dataValue = str_replace(' ', '', $dataValue);
                                 }
                                 $total[$columnIndex] = $dataValue;
                             } else {
                                 if ($columnDataType === 'integer' || $columnDataType === 'float') {
                                     $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']];
                                     if (is_string($dataValue)) {
                                         $dataValue = str_replace(' ', '', $dataValue);
                                     }
                                     $total[$columnIndex] += $dataValue;
                                 }
                             }
                         }
                     }
                     // calculate average values
                     if ($nRows > 1) {
                         foreach ($arColumns as $columnIndex => $viewColumnIndex) {
                             if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') {
                                 $total[$columnIndex] = $total[$columnIndex] / $nRows;
                             }
                         }
                     }
                 }
             }
         }
         // show total
         if ($level === 0) {
             if (count($total) > 0) {
                 // show total check
                 $bShowTotal = false;
                 foreach ($total as $k => $v) {
                     if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) {
                         $bShowTotal = true;
                         break;
                     }
                 }
                 if ($bShowTotal) {
                     $strHtml .= "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL;
                     $strHtml .= "\t\t\t" . '<tr class="adm-list-table-header reports-grouping-total-row">' . PHP_EOL . "\t\t\t\t" . '<td class="adm-list-table-cell">' . htmlspecialcharsbx(GetMessage('REPORT_TOTAL')) . '</td>' . PHP_EOL;
                     foreach ($total as $k => $v) {
                         $cellAlign = '';
                         $cellClass = '';
                         if ($arResult['settings']['red_neg_vals'] === true) {
                             if (is_numeric($v) && $v < 0) {
                                 $cellClass .= ' report-red-neg-val';
                             }
                         }
                         // cell align
                         $colAlign = $arViewColumns[$arColumns[$k]]['align'];
                         if ($colAlign === null) {
                             if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]], $arResult['helperClassName'])) {
                                 $cellAlign = ' align-right';
                             }
                         } else {
                             if ($colAlign === 'right') {
                                 $cellAlign = ' align-right';
                             }
                         }
                         if (!empty($cellAlign)) {
                             $cellClass .= $cellAlign;
                         }
                         $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal'];
                         if ($bGroupingSubtotal) {
                             $finalTotalValue = $v;
                             if (method_exists($arResult['helperClassName'], 'formatResultGroupingTotal')) {
                                 // format subtotal value
                                 $subValueKey = $arViewColumns[$arColumns[$k]]['resultName'];
                                 call_user_func(array($arResult['helperClassName'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]]));
                             }
                         } else {
                             $finalTotalValue = '';
                         }
                         $strHtml .= "\t\t\t\t" . '<td class="adm-list-table-cell' . $cellClass . '">' . ($finalTotalValue === '' ? '&nbsp;' : $finalTotalValue) . '</td>' . PHP_EOL;
                     }
                     $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL;
                 }
             }
             $strHtml .= "\t\t" . '</tbody>' . PHP_EOL . "\t" . '</table>' . PHP_EOL . '</div>' . PHP_EOL;
         }
     }
     $result = array('total' => $total, 'html' => $strHtml);
     // return chart values
     if ($bChartGrouping && $level === 0) {
         $result['chart'] = $arChartGroupingValues;
         $arChartGroupingValues = array();
     }
     return $result;
 }