83 private $columnSQLArray;
94 $pivotArray = array();
96 $date = DateTime::createFromFormat(
"Y-m-d H:i:s", date(
"Y-m").
"-1 00:00:00");
99 for($i = 0; $i <= 12; $i++) {
100 $row = array(
"date" =>
"'" . $date->format(
"Ym") .
"'::varchar",
101 "title" => $date->format(
"M"),
102 "months" => array_fill(0,13, 0),
103 "quarters" => array_fill(0,4,0));
104 $row[
"months"][$i] = 1;
105 $row[
"quarters"][floor($i/4)] = 1;
106 $pivotArray[] = $row;
107 $date->modify(
"-1 month");
109 }
catch(exception $e) {
110 throw new exception (
"Pivot CTE not created correctly: " . $e->getMessage());
113 $this->pivotArray = $pivotArray;
114 $this->columnSQLArray = array();
122 if (isset($this->cte)) {
127 foreach($this->pivotArray as $pivotRow) {
128 $cteArray[] =
"(" . $pivotRow[
"date"] .
"," . implode(
",", $pivotRow[
"months"]) .
"," . implode(
",", $pivotRow[
"quarters"]) .
")";
131 $this->cte =
"with monthPivotCTE(yearmo,m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,q0,q1,q2,q3) as (values " . implode(
",", $cteArray) .
")";
143 if (isset($this->columnSQLArray[$toBeSummed])) {
144 return $this->columnSQLArray[$toBeSummed];
147 $columnArray = array();
148 for($i = 0; $i <= 12; $i++) {
149 $columnArray[] =
"sum($toBeSummed * m$i)";
152 $this->columnSQLArray[$toBeSummed] = implode(
",", $columnArray);
153 return $this->columnSQLArray[$toBeSummed];
165 foreach($this->pivotArray as $pivotRow) {
166 $col = $first ?
"MTD" : $pivotRow[
"title"];
167 $columnArray[$col] =
"number";
182 function GetIsFilterChanged() { ?>
183 function IsFilterChanged(oldFilter, newFilter) {
185 if (oldFilter ==
null) {
186 if (newFilter ==
null) {
191 }
else if (newFilter ==
null) {
195 var oldConstructor = oldFilter.constructor;
196 var newConstructor = newFilter.constructor;
197 var oldLogic, oldFilters, newLogic, newFilters;
198 if (oldConstructor === Array) {
200 oldFilters = oldFilter;
201 }
else if (oldConstructor === Object) {
202 oldLogic = oldFilter.logic ==
null ?
"and" : oldFilter.logic.trim();
203 oldFilters = oldFilter.filters;
208 if (newConstructor === Array) {
210 newFilters = newFilter;
211 }
else if (newConstructor === Object) {
212 newLogic = newFilter.logic ==
null ?
"and" : newFilter.logic.trim();
213 newFilters = newFilter.filters;
218 if (oldLogic != newLogic) {
221 var oldFiltersEmpty = oldFilters ==
null || oldFilters.constructor !== Array || oldFilters.length == 0;
222 var newFiltersEmpty = newFilters ==
null || newFilters.constructor !== Array || newFilters.length == 0;
223 if (oldFiltersEmpty != newFiltersEmpty) {
226 if (oldFilters.length != newFilters.length) {
231 for(var i = 0; i != oldFilters.length; i++) {
232 var record = oldFilters[i];
233 if (record.field ==
null || record.operator ==
null || record.value ==
null) {
236 map[
"" + record.field +
"||" + record.operator +
"||" + record.value] =
true;
238 for(var i = 0; i != newFilters.length; i++) {
239 var record = newFilters[i];
240 if (record.field ==
null || record.operator ==
null || record.value ==
null) {
243 if (map[
"" + record.field +
"||" + record.operator +
"||" + record.value] ==
null) {
266 function GetReportDefinition($schemaData, $pageSize, $pageable, $sort, $filter, $report, $dataUrl, $printerFriendly, $autoBind) {
268 $sort = isset($sort) ? (is_string($sort) ? HCU_JsonDecode($sort) : $sort) : array();
269 $filter = isset($filter) ? (is_string($filter) ? HCU_JsonDecode($filter) : $filter) : array();
272 "serverSorting" =>
true,
"serverFiltering" =>
true,
"serverSorting" =>
true,
"sort" => $sort,
274 "transport" => array(
275 "read" =>
"*** read ***" 278 "model" => $schemaData[
"modelData"],
285 if (isset($schemaData[
"groupData"])) {
286 $dataSource[
"serverGrouping"] =
true;
287 $dataSource[
"group"] = $schemaData[
"groupData"];
288 $dataSource[
"schema"][
"groups"] =
"data";
291 $gridDefinition = array(
292 "dataSource" => $dataSource,
293 "columns" => $schemaData[
"columnData"],
294 "scrollable" =>
false);
296 if (!$printerFriendly) {
297 $gridDefinition[
"dataSource"][
"serverPaging"] =
true;
298 $gridDefinition[
"dataSource"][
"pageSize"] = $pageSize;
299 $gridDefinition[
"pageable"] = $pageable;
300 $gridDefinition[
"sortable"] =
true;
301 $gridDefinition[
"filterable"] = array(
303 "operators" => array(
305 "eq" =>
"Is equal to",
306 "neq" =>
"Is not equal to",
307 "startswith" =>
"Starts with",
308 "endswith" =>
"Ends with",
309 "contains" =>
"Contains",
310 "doesnotcontain" =>
"Does not contain" 313 "eq" =>
"Is equal to",
314 "neq" =>
"Is not equal to",
315 "gt" =>
"Greater than",
316 "gte" =>
"Greater than or equal to",
318 "lte" =>
"Less than or equal to" 321 "eq" =>
"Is equal to",
322 "neq" =>
"Is not equal to",
324 "gte" =>
"Is after or equal to",
326 "lte" =>
"Is before or equal to" 329 "eq" =>
"Is equal to",
330 "neq" =>
"Is not equal to",
334 $gridDefinition[
"dataBound"] =
"*** reportDataBound ***";
335 $gridDefinition[
"pdf"] = array(
"allPages" =>
true,
"avoidLinks" =>
true,
"paperSize" =>
"A4",
"margin" => array(
"top" =>
"2cm",
"left" =>
"1cm",
"right" =>
"1cm",
"bottom" =>
"1cm"),
336 "landscape" =>
true,
"repeatHeaders" =>
true,
"template" =>
"*** \$(\"#pageTemplate\").html() ***",
"fileName" => $report,
"scale" => 0.59);
337 $gridDefinition[
"noRecords"] = array(
"template" =>
"<tr><td>No Records Found</td></tr>");
338 $gridDefinition[
"autoBind"] = $autoBind;
342 $gridDefinition = str_replace(
'"***',
"", str_replace(
'***"',
"", HCU_JsonEncode($gridDefinition)));
343 $gridDefinition = str_replace(
"\\\\",
"\\", str_replace(
"\\/",
"/", str_replace(
'\\"',
'"', $gridDefinition)));
344 return $gridDefinition;
366 function InitReport($reportPage, $report, $reportList, $defaultDateFormat, $pageable =
true, $pageSize = 30, $printerFriendly =
false, $sort =
"", $filter =
"") {
368 $dataUrl = $reportPage . (
false !== strpos($reportPage,
"?") ?
"&" :
"?") .
"operation=readReport";
369 $schemaData = readReportSchema($reportList[$report], $defaultDateFormat);
371 $sort = isset($sort) ? trim($sort) :
"";
372 $filter = isset($filter) ? trim($filter) :
"";
373 $sort = $sort ==
"" ? $schemaData[
"gridConf"][
"sort"] : $sort;
374 $filter = $filter ==
"" ? array() : $filter;
375 $autoBind = HCU_array_key_exists(
"autoBind", $reportList[$report]) ? $reportList[$report][
"autoBind"] === true :
true;
376 $gridDefinition = GetReportDefinition($schemaData[
"gridConf"], $pageSize, $pageable, $sort, $filter, $report, $dataUrl, $printerFriendly, $autoBind);
378 var filterChanged =
true;
380 var inInitial =
false;
382 var currentFilter =
null;
383 var currentSort =
null;
385 function InitReport(funcs) {
386 window.funcs = funcs;
387 var gridDefinition = <?php echo $gridDefinition; ?>;
388 if (funcs !=
null && typeof(funcs.preInitFunc) ==
"function") {
389 (funcs.preInitFunc)(gridDefinition);
392 var grid = $(
"#reportGrid").kendoGrid(gridDefinition).data(
"kendoGrid");
393 <?php
if (!$printerFriendly) { ?>
394 $(grid.pager.element).hide(); <?php
397 var toolTipProps = homecuTooltip.defaults;
398 toolTipProps.filter =
".showEllipsis:overflown";
399 toolTipProps.content =
function(e) {
400 return $(e.target).text().trim();
403 $(
"#groupRightsGrid").kendoTooltip(toolTipProps);
405 <?php
if (!$printerFriendly) { ?>
407 var warningWindow = $(
"<div id='warningWindow'></div>").appendTo(
"body").kendoWindow({
410 title:
"Too Many Records" 411 }).data(
"kendoWindow");
413 var resultSizeLimit = 85000; <?php
414 var warningTemplate = kendo.template(
"<p>You are trying to #: action # with more than #: limit # rows. Please filter more.</p>" 415 +
"<a href='\\#' class='k-button k-primary' id='warningClose'>Close</a>");
417 $(
"#warningWindow").on(
"click",
"#warningClose",
function() {
418 warningWindow.close();
421 $(
"#printBtn").click(
function() {
422 var resultSize = grid.dataSource.total();
423 if (resultSize >= resultSizeLimit) {
424 warningWindow.content(warningTemplate({limit: resultSizeLimit, action:
"print"})).open().center();
428 $(
"#printForm .extraPrintForm").
remove();
429 var sort = grid.dataSource.sort();
430 var filter = grid.dataSource.filter();
431 $(
"#printForm").append(
"<input class='extraPrintForm' name='sort' value='" + kendo.stringify(sort) +
"'>");
432 $(
"#printForm").append(
"<input class='extraPrintForm' name='filter' value='" + kendo.stringify(filter) +
"'>");
433 $(
"#printForm").submit();
436 $(
"#downloadCSVBtn").click(
function () {
437 var resultSize = grid.dataSource.total();
438 if (resultSize >= resultSizeLimit) {
439 warningWindow.content(warningTemplate({limit: resultSizeLimit, action:
"print"})).open().center();
443 $(
"#downloadCSVForm .extraCSVForm").
remove();
444 if (currentSort !=
null) {
445 $(
"#downloadCSVForm").append(
"<input class='extraCSVForm' name='sort' value='" + kendo.stringify(currentSort) +
"'>");
447 if (currentFilter !=
null) {
448 $(
"#downloadCSVForm").append(
"<input class='extraCSVForm' name='filter' value='" + kendo.stringify(currentFilter) +
"'>");
450 $(
"#downloadCSVForm").submit();
453 $(
"#downloadPDFBtn").click(
function() {
454 var toHide = $(grid.wrapper).find(
".k-icon[class^='k-i-sort'], .k-grid-filter");
461 if (funcs !=
null && typeof(funcs.afterInitFunc) ==
"function") {
462 funcs.afterInitFunc();
477 var read =
function(options) {
479 options.success(window.reportInitialData);
482 if (funcs !=
null && typeof(funcs.afterInitFunc) ==
"function") { <?php
483 (funcs.afterInitFunc)(window.reportInitialData);
485 delete window.reportInitialData;
490 var filterChanged = IsFilterChanged(currentFilter, options.data.filter);
491 var parameters = {limit: options.data.pageSize, offset: options.data.skip, report:
"<?php echo $report; ?>", initial: initial,
492 printerFriendly: <?php echo $printerFriendly ?
"true" :
"false"; ?>};
493 parameters.newFilter = initial || filterChanged;
494 if (parameters.newFilter) {
495 currentFilter = options.data.filter;
497 if (options.data.filter !=
null) {
498 parameters.filter = kendo.stringify(options.data.filter);
500 if (options.data.sort !=
null) {
501 parameters.sort = kendo.stringify(options.data.sort);
503 currentSort = options.data.sort;
505 if (funcs !=
null && typeof(funcs.parameterMapFunc) ==
"function") {
506 (funcs.parameterMapFunc) (options.data, parameters, filterChanged);
510 $.post(
"<?php echo $dataUrl; ?>", parameters,
function(data) {
512 if (data.error.length > 0) {
513 $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
517 if (data.booleanRedefinition.length > 0) {
518 window.reportInitialData = data.reportData;
520 var grid = $(
"#reportGrid").data(
"kendoGrid");
522 for(var i = 0, iLength = grid.columns.length; i != iLength; i++) {
523 var iCol = grid.columns[i];
525 if (iCol.columns !=
null) { <?php
526 for(var j = 0, jLength = iCol.columns.length; j != jLength; j++) {
527 var jCol = iCol.columns[j];
528 colMap[jCol.field] = {i: i, j: j};
531 colMap[iCol.field] = {i: i, j: -1};
536 var length = data.booleanRedefinition.length;
537 for(var i = 0; i != length; i++) {
538 var record = data.booleanRedefinition[i];
540 var mappy = colMap[record.col];
542 grid.columns[mappy.i].values = record.values;
544 grid.columns[mappy.i].columns[mappy.j].values = record.values;
548 grid.setOptions({columns: grid.columns});
553 parameters.newFilter ? count = data.reportData.total : data.reportData.total = count;
558 options.success(data.reportData);
570 var reportDataBound =
function(e) {
573 var pager = this.pager.element;
574 var pages = this.dataSource.totalPages();
575 pages <= 1 ? $(pager).hide() : $(pager).show();
577 if (funcs !=
null && typeof(funcs.dataBoundFunc) ==
"function") {
578 (funcs.dataBoundFunc) (
this, e);
597 function InitReportClientSide($reportPage, $report, $title, $additionalParameters = array(), $scrollable =
false, $beforeInitFunc =
"", $afterInitFunc =
"") {
598 $dataUrl = $reportPage . (
false !== strpos($reportPage,
"?") ?
"&" :
"?") .
"operation=readReport";
599 $parameters = array(
"report" => $report,
"limit" => -1,
"offset" => 0,
"includeSchema" =>
"Y");
600 foreach($additionalParameters as $key => $value) {
601 $parameters[$key] = $value;
604 function InitReport() {
608 var currentFilter =
null;
610 $.post(
"<?php echo $dataUrl; ?>", <?php echo HCU_JsonEncode($parameters); ?>,
613 if (topData.error.length > 0) {
614 $.homecuValidator.displayMessage(topData.error, $.homecuValidator.settings.statusError );
616 var sort = {field: topData.columnData[0].field, dir:
"asc"};
617 var gridDefinition = {
620 read:
function (options) {
621 options.success(topData.reportData.data);
625 model: topData.modelData
630 columns: topData.columnData,
636 scrollable: <?php echo ($scrollable ?
"true" :
"false"); ?>
639 <?php echo ($beforeInitFunc !=
"" ?
"($beforeInitFunc) (gridDefinition);" :
""); ?>
641 var grid = $(
"#reportGrid").kendoGrid(gridDefinition).data(
"kendoGrid");
643 $(
"#downloadCSVBtn").click(
function () {
644 downloadCSVClientSide();
647 <?php echo ($afterInitFunc !=
"" ?
"($afterInitFunc) (grid);" :
""); ?>
661 function DownloadCSVClientSide() {
662 var grid = $(
"#reportGrid").data(
"kendoGrid");
666 for(var i = 0, length = grid.columns.length; i!= length; i++) {
667 var record = grid.columns[i];
669 if (record.hidden ==
null || !record.hidden) {
670 columns.push(record.field);
671 csvRecord.push(csvEscape(record.title));
674 csvData.push(csvRecord.join());
676 var data = grid.dataSource.data();
677 var filter = grid.dataSource.filter();
678 var sort = grid.dataSource.sort();
679 var query =
new kendo.data.Query(data);
680 data = query.filter(filter).sort(sort).data;
682 for(var i = 0; i != data.length; i++) {
683 var record = data[i];
686 for(var j = 0; j != grid.columns.length; j++) {
687 if (record.hidden ==
null || !record.hidden) {
688 var column = grid.columns[j];
689 var kendoCol = column.field;
690 var value = column.template !=
null ? kendo.template(record[kendoCol]) : (column.format !=
null ? kendo.format(column.format, record[kendoCol]) : record[kendoCol]);
691 csvRecord.push(csvEscape(value));
695 csvData.push(csvRecord.join());
698 var blob =
new Blob([csvData.join(
"\r\n")], { type:
'text/csv;charset=utf-8;' });
699 var filename =
"<?php echo $title; ?>.csv";
700 if (navigator.msSaveBlob) { <?php
701 navigator.msSaveBlob(blob, filename);
703 var link = document.createElement(
"a");
704 if (link.download !=
null) { <?php
706 var url = URL.createObjectURL(blob);
707 link.setAttribute(
"href", url);
708 link.setAttribute(
"download", filename);
709 link.style.visibility =
'hidden';
710 document.body.appendChild(link);
712 document.body.removeChild(link);
726 function CsvEscape(
string) {
727 if (
string ==
null || typeof(
string) !=
"string") {
730 string =
string.indexOf(
'"') != -1 ?
string.replace(
'"',
'""') : string;
731 string =
string.indexOf(
',') != -1 ||
string.indexOf(
'\n') != -1 ?
'"' +
string +
'"' : string;
742 function GetReportTitles() {
743 $reportList = GetReportList();
744 $reportTitles = array();
745 foreach($reportList as $key => $record) {
746 $reportTitles[$key] = isset($record[
"title"]) ? $record[
"title"] : $key;
748 return $reportTitles;
758 function GetCamelCase($string) {
759 $returnString = $string;
760 if (!isset($string) || trim($string) ==
"") {
763 $camelCase = lcfirst(str_replace(
" ",
"", ucwords(strtolower(trim(preg_replace(
"/[^a-z0-9 ]+/i",
" ", $string))))));
764 $returnString = is_numeric($camelCase[0]) ?
"n$camelCase" : $camelCase;
766 return $returnString;
779 function CompileMenu($conf, $reportList, $reportFrontEndFile, $useRadioButtons =
false) {
781 foreach($conf as $sectionTitle => $reports) {
782 $menu .=
"<div>\n<h2 class='primary'>$sectionTitle</h2>\n<div class='row'>\n";
784 foreach ($reports as $report) {
785 $reportRecord = HCU_array_key_exists($report, $reportList) ? $reportList[$report] : array();
786 $reportTitle = HCU_array_key_exists(
"title", $reportRecord) ? $reportRecord[
"title"] : $report;
787 $href = HCU_array_key_exists(
"url", $reportRecord) ? $reportRecord[
"url"] : $reportFrontEndFile . (
false !== strpos($reportFrontEndFile,
"?") ?
"&" :
"?") .
"report=$report";
789 $menu .=
"<div class='col-xs-6'>\n<a href=$href><span class='reportTitle'>$reportTitle</span></a></div>\n";
791 $menu .=
"</div></div>\n";
803 function UpdateSelectSQL($baseSQL, $colDefs) {
805 if (!isset($baseSQL) || trim($baseSQL) ==
"") {
806 throw new exception(
"BaseSQL needs to be defined.", 1);
808 if (!isset($colDefs) || !is_array($colDefs)) {
809 throw new exception(
"ColDefs needs to be defined.", 2);
812 foreach($colDefs as $colTitle => $colType) {
813 $cols[] = getCamelCase($colTitle);
818 $nonAlphaFound =
false;
819 $selectFound =
false;
821 $inExpression =
true;
828 $baseSQL = trim($baseSQL);
829 for($i = 0, $count = strlen($baseSQL); $i != $count; $i++) {
830 $char = $baseSQL[$i];
832 if(ctype_alnum ($char) || $char ==
"_") {
834 $nonAlphaFound =
false;
836 $willNotBeInExpression =
false;
837 $numInStack = count($stack);
838 $stackEmpty = $numInStack == 0;
839 $lastInStack = $stackEmpty ?
"" : $stack[$numInStack - 1];
841 if ($selectFound && $word !=
"" && !$nonAlphaFound && $stackEmpty) {
842 $inExpression =
false;
845 switch(strtolower($word)) {
847 if (!$selectFound && $stackEmpty) {
849 if ($i > strlen($word) - 1) {
855 if ($selectFound && $stackEmpty) {
860 if ($selectFound && $stackEmpty) {
861 $selectCalc = trim($selectCalc);
862 if (in_array($selectCalc, array(
"select *",
"*"))) {
863 throw new exception(
"Asterisk is not supported at this time.", 4);
865 $doesContain = preg_match(
'/(^| |([a-zA-Z0-9_]+\.))\*$/', $selectCalc);
866 if ($doesContain ===
false) {
867 throw new exception (
"Preg_match failed.", 5);
869 if ($doesContain === 1) {
870 throw new exception(
"Asterisk is not supported at this time.", 6);
872 if ($selectCalc[0] !=
",") {
875 $selectArray .=
"$selectCalc as " . $cols[$selectIndex++];
880 if (!$nonAlphaFound) {
881 array_push($stack, $word);
882 $inExpression =
true;
886 if ($lastInStack ==
"case" && !$nonAlphaFound) {
888 if (count($stack) == 0) {
889 $willNotBeInExpression =
true;
892 $lastInStack = $stack[$numInStack - 2];
897 $inExpression =
true;
901 $nonAlphaFound =
true;
902 if ($fromIndex != -1) {
904 }
else if ($word !=
"") {
906 $selectCalc .= $word;
914 array_push($stack, $char);
915 $inExpression =
true;
919 if ($lastInStack == $char) {
921 if (count($stack) == 0) {
922 $willNotBeInExpression =
true;
925 array_push($stack, $char);
930 if ($lastInStack ==
"{") {
932 if (count($stack) == 0) {
933 $willNotBeInExpression =
true;
938 if ($lastInStack ==
"[") {
940 if (count($stack) == 0) {
941 $willNotBeInExpression =
true;
946 if ($lastInStack ==
"(") {
948 if (count($stack) == 0) {
949 $willNotBeInExpression =
true;
955 $inExpression =
true;
956 if ($selectFound && $stackEmpty) {
957 if (!HCU_array_key_exists($selectIndex, $cols)) {
958 throw new exception(
"Column mismatch found.", 3);
960 $selectCalc = trim($selectCalc);
961 $doesContain = preg_match(
'/(^| |([a-zA-Z0-9_]+\.))\*$/', $selectCalc);
962 if ($doesContain ===
false) {
963 throw new exception (
"Preg_match failed.", 5);
965 if ($doesContain === 1) {
966 throw new exception(
"Asterisk is not supported at this time.", 6);
968 if ($selectCalc[0] !=
",") {
971 $selectArray .=
"$selectCalc as " . $cols[$selectIndex++];
993 $inExpression =
true;
1000 $selectCalc .= $char;
1002 $inExpression = !$willNotBeInExpression;
1007 $restOfSQL = substr($baseSQL, $fromIndex);
1008 $baseSQL = trim($selectArray) .
" from " . trim($restOfSQL);
1010 $returnArray = array(
"status" =>
"000",
"error" =>
"",
"modifiedSQL" => $baseSQL);
1011 }
catch (exception $e) {
1012 $returnArray = array(
"status" => $e->getCode(),
"error" => $e->getMessage());
1015 return $returnArray;
1035 function FormatReportData($Cu, $dbh, $unprocessedDataArray, $cols, $groupBy, $groupDescription, $dontIncludeId, $initial, &$booleanRedefinition, $dataFunc, $dataFuncVariables) {
1036 $reportData = array();
1037 $booleanFields = array();
1039 $idName =
"reportId";
1040 $datetimeFields = array();
1042 foreach($cols as $colTitle => $colType) {
1043 $value = getCamelCase($colTitle);
1044 $key = strtolower($value);
1045 $colMap[$key] = $value;
1047 if ($colType ==
"boolean") {
1048 $booleanFields[$value] = array(
"trueFound" =>
false,
"falseFound" =>
false,
"trueValue" =>
"",
"falseValue" =>
"");
1049 }
else if ($colType ==
"datetime") {
1051 $datetimeFields[$key] =
true;
1052 $tz = GetCreditUnionTimezone($dbh, $Cu);
1058 foreach($unprocessedDataArray as $i => $dRecord) {
1059 $kendoRecord = array();
1060 if (!$dontIncludeId) {
1061 $kendoRecord[$idName] = $i;
1064 foreach($dRecord as $key => $value) {
1065 $kendoCol = $colMap[strtolower($key)];
1066 $value = trim($value);
1067 $value = isset($booleanFields[$kendoCol]) ? ($value ==
"t" ? true : ($value ==
"" || $value ==
"f" ? false : $value)) : $value;
1068 $kendoRecord[$kendoCol] = $value;
1070 CaptureBooleanValues($booleanFields, $kendoCol, $value);
1072 if (HCU_array_key_exists($key, $datetimeFields) && $value !=
"") {
1074 $dateTime =
new DateTime($value);
1075 $dateTime->setTimezone(
new DateTimeZone($tz));
1076 $kendoRecord[$kendoCol] = $dateTime->format(
"Y-m-d H:i:s.u") .
"Z";
1081 if ($dataFunc !=
"") {
1082 $dataFunc($Cu, $dbh, $kendoRecord, $dataFuncVariables);
1085 if ($groupBy !=
"") {
1086 $groupCol = GetCamelCase($groupBy);
1087 $groupValue = $kendoRecord[$groupCol];
1089 if ($first || $groupValue != $currentGroup) {
1090 $currentGroup = $groupValue;
1091 $reportData[$groupValue] = array(
"field" => $groupCol,
"value" => $groupValue,
"items" => array(),
"hasSubgroups" =>
false,
"aggregates" => array());
1093 if ($groupDescription !=
"") {
1094 $descCol = GetCamelCase($groupDescription);
1095 $reportData[$groupValue][
"aggregates"][$descCol][
"max"] = $kendoRecord[$descCol];
1099 $reportData[$groupValue][
"items"][] = $kendoRecord;
1101 $reportData[] = $kendoRecord;
1107 if ($initial && count($booleanFields) > 0) {
1108 foreach($booleanFields as $boolCol => $booleanItem) {
1109 $booleanRedefinition[$boolCol] = array(
"col" => $boolCol,
1110 "values" => array(array(
"text" =>
"Y",
"value" => $booleanItem[
"trueValue"]), array(
"text" =>
"N",
"value" => $booleanItem[
"falseValue"])));
1112 $booleanRedefinition = array_values($booleanRedefinition);
1114 return $groupBy !=
"" ? array_values($reportData) : $reportData;
1125 function CaptureBooleanValues(&$booleanFields, $kendoCol, $value) {
1126 if (HCU_array_key_exists($kendoCol, $booleanFields)) {
1127 $falseFound = $booleanFields[$kendoCol][
"falseFound"];
1128 $trueFound = $booleanFields[$kendoCol][
"trueFound"];
1129 $updateTrue =
false;
1130 $updateFalse =
false;
1131 if (!$trueFound || !$falseFound) {
1135 $booleanFields[$kendoCol][
"falseValue"] =
"No";
1141 $booleanFields[$kendoCol][
"falseValue"] =
"no";
1147 $booleanFields[$kendoCol][
"falseValue"] =
"N";
1153 $booleanFields[$kendoCol][
"falseValue"] =
"n";
1159 $booleanFields[$kendoCol][
"falseValue"] =
"0";
1165 $booleanFields[$kendoCol][
"falseValue"] =
"false";
1171 $booleanFields[$kendoCol][
"falseValue"] =
"False";
1177 $booleanFields[$kendoCol][
"trueValue"] =
"Yes";
1179 $updateFalse =
true;
1183 $booleanFields[$kendoCol][
"trueValue"] =
"yes";
1185 $updateFalse =
true;
1189 $booleanFields[$kendoCol][
"trueValue"] =
"y";
1191 $updateFalse =
true;
1195 $booleanFields[$kendoCol][
"trueValue"] =
"Y";
1197 $updateFalse =
true;
1201 $booleanFields[$kendoCol][
"trueValue"] =
"1";
1203 $updateFalse =
true;
1207 $booleanFields[$kendoCol][
"trueValue"] =
"true";
1209 $updateFalse =
true;
1213 $booleanFields[$kendoCol][
"trueValue"] =
"True";
1215 $updateFalse =
true;
1218 $updateFalse =
true;
1222 $booleanFields[$kendoCol][
"trueValue"] = $value;
1223 $booleanFields[$kendoCol][
"trueFound"] =
true;
1224 $kendoRecord[$kendoCol] =
true;
1225 }
else if ($updateFalse) {
1226 $booleanFields[$kendoCol][
"falseValue"] = $value;
1227 $booleanFields[$kendoCol][
"falseFound"] =
true;
1228 $kendoRecord[$kendoCol] =
false;
1247 function AddSort($sort, $cols, $groupBy, $groupDescription, $groupForceSortBy, $defaultSort) {
1248 $colTypeMap = array();
1253 foreach($cols as $colTitle => $colType) {
1254 $colTypeMap[getCamelCase($colTitle)] = $colType;
1257 if ($groupBy !=
"") {
1258 $groupCol = getCamelCase($groupDescription !=
"" && !$groupForceSortBy ? $groupDescription : $groupBy);
1259 $sortSQL[] =
"$groupCol asc";
1263 $sort = HCU_JsonDecode($sort);
1264 if (!is_array($sort)) {
1265 throw new exception(
"Sort is not a valid array.", 401);
1268 foreach($sort as $sortItem) {
1269 if (!HCU_array_key_exists(
"field", $sortItem) || !HCU_array_key_exists(
"dir", $sortItem)) {
1270 throw new exception(
"Sort is not a valid array.", 402);
1272 if (!in_array($sortItem[
"dir"], array(
"asc",
"desc"))) {
1273 throw new exception(
"Sort is not a valid array.", 403);
1275 $sortSQL[] = getSortCol($sortItem[
"field"], $colTypeMap[$sortItem[
"field"]]) .
" " . $sortItem[
"dir"];
1277 }
else if (isset($defaultSort)) {
1278 if (!is_array($defaultSort)) {
1279 throw new exception(
"Sort is not a valid array.", 404);
1282 foreach($defaultSort as $sortItem) {
1283 if (!HCU_array_key_exists(
"field", $sortItem) || !HCU_array_key_exists(
"dir", $sortItem)) {
1284 throw new exception(
"Sort is not a valid array.", 402);
1286 if (!in_array($sortItem[
"dir"], array(
"asc",
"desc"))) {
1287 throw new exception(
"Sort is not a valid array.", 403);
1289 $sortSQL[] = getSortCol($sortItem[
"field"], $colTypeMap[$sortItem[
"field"]]) .
" " . $sortItem[
"dir"];
1292 foreach($cols as $colTitle => $colType) {
1293 if ($colType !=
"ignore" && $colType !=
"hidden") {
1294 $sortCol = getSortCol(getCamelCase($colTitle), $colType);
1295 $sortSQL[] =
"$sortCol asc";
1302 if (isset($sortSQL) && count($sortSQL) != 0) {
1303 $appendToSQL .=
" order by " . implode(
", ", $sortSQL);
1306 $returnArray = array(
"appendToSQL" => $appendToSQL,
"status" =>
"000",
"error" =>
"");
1307 }
catch (exception $e) {
1308 $returnArray = array(
"appendToSQL" =>
"",
"status" => $e->getCode(),
"error" => $e->getMessage());
1311 return $returnArray;
1327 function AddNonSqlSort($unprocessedDataArray, $sort, $cols, $groupBy, $groupDescription, $groupForceSortBy) {
1328 $colTypeMap = array();
1329 $compArray = array();
1330 $returnArray = array(
"data" => $unprocessedDataArray,
"status" =>
"000",
"error" =>
"");
1332 foreach($cols as $colTitle => $colType) {
1333 $colTypeMap [GetCamelCase($colTitle)] = $colType;
1336 if ($groupBy !=
"") {
1337 $groupCol = GetCamelCase($groupDescription !=
"" && !$groupForceSortBy ? $groupDescription : $groupBy);
1338 $compArray [] = array(
"field" => $groupCol,
"type" =>
"string",
"dir" =>
"asc");
1342 $sort = HCU_JsonDecode($sort);
1343 if (!is_array($sort)) {
1344 throw new exception(
"Sort is not a valid array.", 401);
1347 foreach($sort as $sortItem) {
1349 if (!HCU_array_key_exists(
"field", $sortItem) || !HCU_array_key_exists(
"dir", $sortItem)) {
1350 throw new exception(
"Sort is not a valid array.", 402);
1353 if (!in_array($sortItem[
"dir"], array(
"asc",
"desc"))) {
1354 throw new exception(
"Sort is not a valid array.", 403);
1357 $compArray [] = array(
"field" => $sortItem[
"field"],
"type" => $colTypeMap[$sortItem[
"field"]],
"dir" => $sortItem[
"dir"]);
1361 if (count($sort) > 0) {
1362 usort($unprocessedDataArray,
function($a, $b) use ($compArray) {
1363 return CmpSort($a, $b, $compArray);
1367 $returnArray = array(
"data" => $unprocessedDataArray,
"status" =>
"000",
"error" =>
"");
1369 }
catch (exception $e) {
1370 $returnArray = array(
"data" => array(),
"status" => $e->getCode(),
"error" => $e->getMessage());
1373 return $returnArray;
1385 function GetSortCol($sortCol, $type, $isFilter =
false) {
1386 $sortCol =
'"' . strtolower($sortCol) .
'"';
1392 return "lower(trim(coalesce($sortCol::varchar, '')))";
1396 return "$sortCol::decimal";
1399 return "(case when trim(coalesce($sortCol::varchar, '')) = '' then null else $sortCol end)::" . ($isFilter ?
"date" :
"timestamp");
1413 function CmpSort($a, $b, $sortArray) {
1415 foreach($sortArray as $sortRow) {
1416 switch($sortRow[
"type"]) {
1425 $aCmp = trim($a[$sortRow[
"field"]]);
1426 $bCmp = trim($b[$sortRow[
"field"]]);
1427 $cmp = $sortRow[
"dir"] ==
"asc" ? strcmp($aCmp, $bCmp) : strcmp($bCmp, $aCmp);
1430 $aCmp = $a[$sortRow[
"field"]];
1431 $bCmp = $b[$sortRow[
"field"]];
1432 $aCmp = $aCmp ===
true ? 1 : ($aCmp ===
false ? 0 : (in_array(strtolower(trim(strval($aCmp))), array(
"true",
"t",
"y",
"yes",
"1")) ? 1 : 0));
1433 $bCmp = $bCmp ===
true ? 1 : ($bCmp ===
false ? 0 : (in_array(strtolower(trim(strval($bCmp))), array(
"true",
"t",
"y",
"yes",
"1")) ? 1 : 0));
1434 $cmp = $sortRow[
"dir"] ==
"asc" ? $aCmp - $bCmp : $bCmp - $aCmp;
1439 $aCmp = floatval($a[$sortRow[
"field"]]);
1440 $bCmp = floatval($b[$sortRow[
"field"]]);
1441 $cmp = $sortRow[
"dir"] ==
"asc" ? $aCmp - $bCmp : $bCmp - $aCmp;
1445 $aCmp = strtotime($a[$sortRow[
"field"]]);
1446 $bCmp = strtotime($b[$sortRow[
"field"]]);
1447 $cmp = $sortRow[
"dir"] ==
"asc" ? $aCmp - $bCmp : $bCmp - $aCmp;
1467 function AddFilter($filter, $cols) {
1469 $appendToSQL = array();
1472 if ($filter !=
"") {
1473 $filter = HCU_JsonDecode($filter);
1474 if (!is_array($filter)) {
1475 throw new exception(
"Filter is not a valid array.", 501);
1477 if (!HCU_array_key_exists(
"logic", $filter) || !HCU_array_key_exists(
"filters", $filter)) {
1478 throw new exception(
"Filter is not a valid array.", 502);
1480 if (!in_array($filter[
"logic"], array(
"and",
"or"))) {
1481 throw new exception(
"Filter is not a valid array.", 503);
1484 $opStartMap = array(
"eq" =>
"= '",
"neq" =>
"<> '",
"lt" =>
"< '",
"lte" =>
"<= '",
"gt" =>
"> '",
"gte" =>
">= '",
"startswith" =>
"like '",
"contains" =>
"like '%",
1485 "endswith" =>
"like '%",
"doesnotcontain" =>
"not like '%");
1486 $opEndMap = array(
"eq" =>
"'",
"neq" =>
"'",
"lt" =>
"'",
"lte" =>
"'",
"gt" =>
"'",
"gte" =>
"'",
"startswith" =>
"%'",
"contains" =>
"%'",
"endswith" =>
"'",
"doesnotcontain" =>
"%'");
1489 foreach($cols as $colTitle => $colValue) {
1490 $key = GetCamelCase($colTitle);
1491 $colMap[$key] = $colTitle;
1494 foreach($filter[
"filters"] as $filterItem) {
1495 if (HCU_array_key_exists(
"logic", $filterItem) || HCU_array_key_exists(
"filters", $filterItem)) {
1496 throw new exception(
"At this time, multiple levels of filters are not allowed.", 504);
1498 if (!HCU_array_key_exists(
"field", $filterItem) || !HCU_array_key_exists(
"operator", $filterItem) || !HCU_array_key_exists(
"value", $filterItem)) {
1499 throw new exception(
"Filter is not a valid array.", 505);
1501 $databaseCol = trim($filterItem[
"field"]);
1502 $op = strtolower(trim($filterItem[
"operator"]));
1503 $value = prep_save(strtolower(trim($filterItem[
"value"])));
1506 $fullOp = $op ==
"isnull" ?
"\"" . strtolower($databaseCol) .
"\" is null" : ($op ==
"isnotnull" ?
"\"" . strtolower($databaseCol) .
"\" is not null" :
1507 getSortCol($databaseCol, $cols[$colMap[$databaseCol]],
true) .
" " . $opStartMap[$op] . trim($value) . $opEndMap[$op]);
1509 $appendToSQL[] = $fullOp;
1513 $appendToSQL = count($appendToSQL) == 0 ?
"" :
" where (" . implode(
") " . $filter[
"logic"] .
" (", $appendToSQL) .
")";
1515 $returnArray = array(
"appendToSQL" => $appendToSQL,
"status" =>
"000",
"error" =>
"");
1516 }
catch (exception $e) {
1517 $returnArray = array(
"appendToSQL" =>
"",
"status" => $e->getCode(),
"error" => $e->getMessage());
1520 return $returnArray;
1536 function AddNonSqlFilter($unprocessedDataArray, $filter, $cols) {
1537 $returnArray = array(
"data" => $unprocessedDataArray,
"status" =>
"000",
"error" =>
"");
1539 if ($filter !=
"") {
1540 $filter = HCU_JsonDecode($filter);
1541 if (!is_array($filter)) {
1542 throw new exception(
"Filter is not a valid array.", 501);
1544 if (!HCU_array_key_exists(
"logic", $filter) || !HCU_array_key_exists(
"filters", $filter)) {
1545 throw new exception(
"Filter is not a valid array.", 502);
1547 if (!in_array($filter[
"logic"], array(
"and",
"or"))) {
1548 throw new exception(
"Filter is not a valid array.", 503);
1553 foreach($cols as $colTitle => $colValue) {
1554 $key = getCamelCase($colTitle);
1555 $colMap[$key] = $colTitle;
1558 $simplifiedTypeMap = array(
"number" =>
"number",
"decimal" =>
"number",
"currency" =>
"number",
"string" =>
"string",
"list" =>
"string",
"date" =>
"date",
"odata" =>
"string",
1559 "boolean" =>
"boolean",
"ignore" =>
"string",
"hidden" =>
"string",
"description" =>
"string",
"unencoded" =>
"string",
"datetime" =>
"date");
1561 $filterArray = array();
1562 $logic = $filter[
"logic"];
1563 foreach($filter[
"filters"] as $filterItem) {
1564 if (HCU_array_key_exists(
"logic", $filterItem) || HCU_array_key_exists(
"filters", $filterItem)) {
1565 throw new exception(
"At this time, multiple levels of filters are not allowed.", 504);
1567 if (!HCU_array_key_exists(
"field", $filterItem) || !HCU_array_key_exists(
"operator", $filterItem) || !HCU_array_key_exists(
"value", $filterItem)) {
1568 throw new exception(
"Filter is not a valid array.", 505);
1571 $field = trim($filterItem[
"field"]);
1572 $type = $cols[$colMap[$field]];
1573 $type = $simplifiedTypeMap[$type];
1575 $filterArray [] = array(
"field" => $field,
"operator" => strtolower(trim($filterItem[
"operator"])),
"value" => strtolower(trim($filterItem[
"value"])),
1579 $unprocessedDataArray = array_filter($unprocessedDataArray,
function($value) use ($filterArray, $logic) {
1580 return CmpFilter($value, $filterArray, $logic);
1586 $returnArray = array(
"data" => array_values($unprocessedDataArray),
"status" =>
"000",
"error" =>
"");
1588 }
catch (exception $e) {
1589 $returnArray = array(
"data" => array(),
"status" => $e->getCode(),
"error" => $e->getMessage());
1592 return $returnArray;
1603 function CmpFilter($dataRow, $filterArray, $logic) {
1606 foreach($filterArray as $filterRow) {
1607 $dataValue = $dataRow[$filterRow[
"field"]];
1608 $filterValue = $filterRow[
"value"];
1609 $filterValueLength = strlen($filterValue);
1614 $dataDateFormat =
"";
1615 $filterDateFormat =
"";
1616 $filterBoolean =
null;
1617 $dataBoolean =
null;
1618 if ($filterRow[
"type"] ==
"date") {
1619 $dataDate = DateTime::createFromFormat(
"Y-m-d H:i:s+|", $dataValue);
1620 $dataDate = !$dataDate ? DateTime::createFromFormat(
"Y-m-d+|", $dataValue) : $dataDate;
1621 $filterDate = DateTime::createFromFormat(
"Y-m-d H:i:s+|", $filterValue);
1622 $filterDate = !$filterDate ? DateTime::createFromFormat(
"Y-m-d+|", $filterValue) : $filterDate;
1623 $dataDateFormat = $dataDate->format(
"Y-m-d");
1624 $filterDateFormat = $filterDate->format(
"Y-m-d");
1625 }
else if ($filterRow[
"type"] ==
"boolean") {
1626 $dataBoolean = $dataValue ===
true ? 1 : ($dataValue ===
false ? 0 : (in_array(strtolower(trim(strval($dataValue))), array(
"true",
"t",
"y",
"yes",
"1")) ? 1 : 0));
1627 $filterBoolean = $filterValue ===
true ? 1 : ($filterValue ===
false ? 0 : (in_array(strtolower(trim(strval($filterValue))), array(
"true",
"t",
"y",
"yes",
"1")) ? 1 : 0));
1628 }
else if ($filterRow[
"type"] ==
"string") {
1629 $dataValue = trim(strtolower($dataValue));
1630 $filterValue = trim(strtolower($filterValue));
1633 switch ($filterRow[
"type"] .
" | " . $filterRow[
"operator"]) {
1634 case "number | eq": $cmp = floatval($dataValue) == floatval($filterValue);
break;
1635 case "number | neq": $cmp = floatval($dataValue) != floatval($filterValue);
break;
1636 case "number | lt": $cmp = floatval($dataValue) < floatval($filterValue);
break;
1637 case "number | lte": $cmp = floatval($dataValue) <= floatval($filterValue);
break;
1638 case "number | gt": $cmp = floatval($dataValue) > floatval($filterValue);
break;
1639 case "number | gte": $cmp = floatval($dataValue) >= floatval($filterValue);
break;
1640 case "string | eq": $cmp = strcmp($dataValue, $filterValue) == 0;
break;
1641 case "string | neq": $cmp = strcmp($dataValue, $filterValue) != 0;
break;
1642 case "string | startswith": $cmp = substr($dataValue, 0, $filterValueLength) == $filterValue;
break;
1643 case "string | endswith": $cmp = substr($dataValue, -$filterValueLength) == $filterValue;
break;
1644 case "string | contains": $cmp = strpos($dataValue, $filterValue) !==
false;
break;
1645 case "string | doesnotcontain": $cmp = strpos($dataValue, $filterValue) ===
false;
break;
1646 case "date | eq": $cmp = strcmp($dataDateFormat, $filterDateFormat) == 0;
break;
1647 case "date | neq": $cmp = strcmp($dataDateFormat, $filterDateFormat) != 0;
break;
1648 case "date | gt": $cmp = $dataDate > $filterDate;
break;
1649 case "date | gte": $cmp = $dataDate >= $filterDate;
break;
1650 case "date | lt": $cmp = $dataDate < $filterDate;
break;
1651 case "date | lte": $cmp = $dataDate <= $filterDate;
break;
1652 case "boolean | eq": $cmp = intval($dataBoolean) == intval($filterBoolean);
break;
1653 case "boolean | neq": $cmp = intval($dataBoolean) != intval($filterBoolean);
break;
1654 case "boolean | isnull": $cmp = !isset($dataValue);
break;
1655 case "boolean | isnotnull": $cmp = isset($dataValue);
break;
1658 $keepRow = $logic ==
"and" ? $keepRow && $cmp : $keepRow || $cmp;
1660 if (($logic ==
"and" && !$keepRow) || ($logic ==
"or" && $keepRow)) {
1692 function ReadReportData($Cu, $reportRecord, $dbh, $limit, $offset, $includeCount, $dontIncludeId, $initial, $excludeSort, $sort, $filter, $report, $cookieName) {
1695 validateReportRecord($reportRecord);
1697 $baseSQL = HCU_array_key_exists(
"sql", $reportRecord) ? $reportRecord[
"sql"] :
"";
1698 $nonSqlDataFunc = HCU_array_key_exists(
"nonSqlDataFunc", $reportRecord) ? $reportRecord[
"nonSqlDataFunc"] :
"";
1700 $cols = HCU_array_key_exists(
"cols", $reportRecord) ? $reportRecord[
"cols"] : array();
1701 $groupBy = HCU_array_key_exists(
"groupBy", $reportRecord) ? trim($reportRecord[
"groupBy"]) :
"";
1702 $groupDescription = HCU_array_key_exists(
"groupDescription", $reportRecord) ? trim($reportRecord[
"groupDescription"]) :
"";
1703 $groupForceSortBy = HCU_array_key_exists(
"groupForceSortBy", $reportRecord) ? $reportRecord[
"groupForceSortBy"] :
false;
1704 $dataFunc = HCU_array_key_exists(
"dataFunc", $reportRecord) ? trim($reportRecord[
"dataFunc"]) :
"";
1705 $dataFuncVariables = HCU_array_key_exists(
"dataFuncVariables", $reportRecord) ? $reportRecord[
"dataFuncVariables"] : array();
1706 $defaultSort = HCU_array_key_exists(
"defaultSort", $reportRecord) ? $reportRecord[
"defaultSort"] :
null;
1709 if (isset($replaceString) && isset($replaceCode)) {
1711 $replaceCodeString =
"";
1712 $cookieExists =
false;
1713 if (isset($_COOKIE[$cookieName])) {
1714 parse_str($_COOKIE[$cookieName], $cookie);
1715 $cookieExists =
true;
1718 if ($cookieExists && isset($cookie[$report]) && trim($cookie[$report]) !=
"") {
1719 $replaceCodeString = trim($cookie[$report]);
1721 $replaceCodeString = eval($replaceCode);
1722 $cookie[$report] = $replaceCodeString;
1723 $expiresInDay = time() + 86400;
1725 setcookie($cookieName, http_build_query($cookie), $expiresInDay,
"/", $_SERVER[
'SERVER_NAME']);
1727 $baseSQL = str_replace($replaceString, $replaceCodeString, $baseSQL);
1731 if ($baseSQL !=
"") {
1732 $results = UpdateSelectSQL($baseSQL, $cols);
1733 if ($results[
"status"] !==
"000") {
1734 throw new exception(
"Update Select SQL failed.", 211);
1736 $baseSQL = $results[
"modifiedSQL"];
1738 $fullSQL =
"select * from ($baseSQL) t";
1739 $countSQL =
"select count(*) from ($baseSQL) t";
1742 $results = AddFilter($filter, $cols);
1743 if ($results[
"status"] !=
"000") {
1744 throw new exception(
"SQL didn't filter correctly.", 210);
1747 $fullSQL .= $results[
"appendToSQL"];
1748 $countSQL .= $results[
"appendToSQL"];
1750 if (!$excludeSort) {
1751 $results = AddSort($sort, $cols, $groupBy, $groupDescription, $groupForceSortBy, $defaultSort);
1752 if ($results[
"status"] !=
"000") {
1753 throw new exception(
"SQL didn't sort correctly.", 209);
1756 $fullSQL .= $results[
"appendToSQL"];
1760 $fullSQL .=
" limit $limit offset $offset";
1764 $sth = db_query($fullSQL, $dbh);
1766 $unprocessedDataArray = db_fetch_all($sth);
1769 $unprocessedDataArray = !$unprocessedDataArray ? array() : $unprocessedDataArray;
1772 $sqls[] = $countSQL;
1773 $sth = db_query($sql,$dbh);
1775 throw new exception(
"Count SQL failed.", 201);
1778 list($count) = db_fetch_array($sth,0);
1780 }
else if ($nonSqlDataFunc) {
1783 $results = $nonSqlDataFunc($Cu, $dbh);
1785 if (!isset($results)) {
1786 throw new exception(
"Data function is not formatted correctly.", 206);
1787 }
else if (!HCU_array_key_exists(
"status", $results) || !HCU_array_key_exists(
"error", $results) || !HCU_array_key_exists(
"data", $results)) {
1788 throw new exception(
"Data function is not formatted correctly.", 207);
1789 }
else if ($results[
"status"] !==
"000") {
1790 throw new exception ($results[
"error"], 208);
1793 if (HCU_array_key_exists(
"sql", $results)) {
1794 $sqls = $results[
"sql"];
1797 $rawData = $results[
"data"];
1798 $unprocessedDataArray = array();
1801 $colCount = count($cols);
1802 $colnames = array();
1803 foreach($cols as $colTitle => $colType) {
1804 $colnames[] = getCamelCase($colTitle);
1806 foreach($rawData as $dataRow) {
1807 if (count($dataRow) != $colCount) {
1808 throw new exception (
"Data from function doesn't return columns necessary for the report.", 203);
1811 $unprocessedDataArray [] = array_combine ($colnames, $dataRow);
1815 $results = AddNonSqlFilter($unprocessedDataArray, $filter, $cols);
1817 if ($results [
"status"] !=
"000") {
1818 throw new exception (
"Data did not filter correctly.", 204);
1821 $unprocessedDataArray = $results [
"data"];
1823 $count = count($unprocessedDataArray);
1826 $results = AddNonSqlSort($unprocessedDataArray, $sort, $cols, $groupBy, $groupDescription, $groupForceSortBy);
1828 if ($results [
"status"] !=
"000") {
1829 throw new exception (
"Data did not filter correctly.", 205);
1832 $unprocessedDataArray = $results [
"data"];
1836 $unprocessedDataArray = array_slice($unprocessedDataArray, $offset, $limit);
1840 throw new exception (
"Either the 'sql' or the 'nonSqlDataFunc' need to be defined.", 202);
1843 $booleanRedefinition = array();
1844 $reportData = FormatReportData($Cu, $dbh, $unprocessedDataArray, $cols, $groupBy, $groupDescription, $dontIncludeId, $initial, $booleanRedefinition, $dataFunc, $dataFuncVariables);
1846 $reportData = array(
"total" => -1,
"data" => $reportData);
1847 if ($includeCount) {
1848 $reportData[
"total"] = $count;
1851 $returnArray = array(
"error" => array(),
"status" =>
"000",
"reportData" => $reportData,
"sql" => $sqls,
"booleanRedefinition" => $booleanRedefinition);
1852 }
catch(exception $e) {
1853 $returnArray = array(
"error" => array($e->getMessage()),
"status" => $e->getCode(),
"reportData" => array(),
"sql" => $sqls);
1855 return $returnArray;
1874 function ReadReportSchema($reportRecord, $defaultDateFormat) {
1876 ValidateReportRecord($reportRecord);
1878 $modelData = array();
1879 $columnData = array();
1882 $dateFormat = HCU_array_key_exists(
"dateFormat", $reportRecord) ? trim($reportRecord[
"dateFormat"]) : null;
1883 $format = isset($dateFormat) ? trim($dateFormat) : (isset($defaultDateFormat) ? trim($defaultDateFormat) :
"");
1884 $dateIfNull = HCU_array_key_exists(
"dateEmpty", $reportRecord) ? trim($reportRecord[
"dateEmpty"]) : null;
1885 $replaceString = HCU_array_key_exists(
"replaceString", $reportRecord) ? trim($reportRecord[
"replaceString"]) : null;
1886 $replaceCode = HCU_array_key_exists(
"replaceCode", $reportRecord) ? trim($reportRecord[
"replaceCode"]) : null;
1887 $values = HCU_array_key_exists(
"ddl", $reportRecord) ? $reportRecord[
"ddl"] :
null;
1888 $groupBy = HCU_array_key_exists(
"groupBy", $reportRecord) ? trim($reportRecord[
"groupBy"]) : null;
1889 $groupDescription = HCU_array_key_exists(
"groupDescription", $reportRecord) ? trim($reportRecord[
"groupDescription"]) : null;
1890 $cols = HCU_array_key_exists(
"cols", $reportRecord) ? $reportRecord[
"cols"] : array();
1891 $colHeader = HCU_array_key_exists(
"colHeader", $reportRecord) ? $reportRecord[
"colHeader"] : array();
1892 $schemaFunc = HCU_array_key_exists(
"schemaFunc", $reportRecord) ? $reportRecord[
"schemaFunc"] :
"";
1893 $defaultSort = HCU_array_key_exists(
"defaultSort", $reportRecord) ? $reportRecord[
"defaultSort"] :
null;
1895 $fieldData = array();
1897 if (count($colHeader) > 0) {
1898 foreach($colHeader as $header => $lastColumn) {
1899 $title = explode(
".", $header)[0];
1900 $columnData[] = array(
"title" => $title,
"columns" => array(),
"lastColumn" => $lastColumn);
1905 $sort = array(
"dir" =>
"asc");
1907 foreach($cols as $colTitle => $colType) {
1908 $kendoCol = getCamelCase($colTitle);
1909 $fieldRecord = array();
1910 $newTitle = explode(
".", $colTitle);
1911 $newTitle = $newTitle[0];
1912 $columnRecord = array(
"field" => $kendoCol,
"title" => $newTitle);
1913 if ($colType ==
"ignore" || $colType ==
"boolean") {
1914 $fieldRecord[
"type"] =
"string";
1915 }
else if ($colType ==
"unencoded") {
1916 $fieldRecord[
"type"] =
"string";
1917 $columnRecord[
"encoded"] =
false;
1918 }
else if ($colType ==
"hidden") {
1919 $fieldRecord[
"type"] =
"string";
1920 $columnRecord[
"hidden"] =
true;
1921 }
else if ($colType ==
"date" || $colType ==
"datetime") {
1922 $fieldRecord[
"type"] =
"date";
1923 if ($format !=
"") {
1924 $columnRecord[
"template"] =
"# if ($kendoCol == null || $kendoCol == '') { # $dateIfNull # } else { # #: kendo.toString(new Date($kendoCol), '$format') # # } #";
1926 }
else if ($colType ==
"number") {
1927 $fieldRecord[
"type"] =
"number";
1928 $columnRecord[
"attributes"] = array(
"class" =>
"textAlignRight");
1929 $columnRecord[
"headerAttributes"] = array(
"class" =>
"textAlignRight");
1930 }
else if ($colType ==
"decimal") {
1931 $fieldRecord[
"type"] =
"number";
1932 $columnRecord[
"attributes"] = array(
"class" =>
"textAlignRight");
1933 $columnRecord[
"headerAttributes"] = array(
"class" =>
"textAlignRight");
1934 $columnRecord[
"format"] =
"{0:n}";
1935 }
else if ($colType ==
"currency") {
1936 $fieldRecord[
"type"] =
"number";
1937 $columnRecord[
"attributes"] = array(
"class" =>
"textAlignRight");
1938 $columnRecord[
"headerAttributes"] = array(
"class" =>
"textAlignRight");
1939 $columnRecord[
"format"] =
"{0:c2}";
1940 }
else if ($colType ==
"list") {
1941 $fieldRecord[
"type"] =
"string";
1944 foreach($values[$colTitle] as $value => $text) {
1945 $ddl[] = array(
"text" => $text,
"value" => $value);
1947 $columnRecord[
"values"] = $ddl;
1948 }
else if ($colType ==
"description") {
1949 $fieldRecord[
"type"] =
"string";
1950 $columnRecord[
"attributes"] = array(
"class" =>
"showEllipsis");
1951 $columnRecord[
"width"] = 100;
1953 $fieldRecord[
"type"] = $colType;
1956 if (isset($groupBy) && $groupBy == $colTitle) {
1957 $groupData = array(
"field" => $kendoCol);
1959 if (isset($groupDescription)) {
1960 $groupDescCol = getCamelCase($groupDescription);
1961 $groupData[
"aggregates"] = array(array(
"field" => $groupDescCol,
"aggregate" =>
"max"));
1962 $columnRecord[
"groupHeaderTemplate"] =
"#: aggregates.$groupDescCol.max #";
1964 $columnRecord[
"groupHeaderTemplate"] =
"#: value #";
1968 $fieldData[$kendoCol] = $fieldRecord;
1970 if ($schemaFunc !=
"") {
1971 $schemaFunc($Cu, $colTitle, $colType, $kendoCol, $columnRecord);
1974 if ($colType !=
"ignore") {
1975 if (count($colHeader) > 0) {
1976 $key = key($columnData);
1977 $columnData[$key][
"columns"][] = $columnRecord;
1978 if ($colTitle == $columnData[$key][
"lastColumn"]) {
1979 unset($columnData[$key][
"lastColumn"]);
1983 $columnData[] = $columnRecord;
1986 if ($first && $colType !=
"hidden") {
1987 if (isset($defaultSort)) {
1988 $sort = $defaultSort;
1990 $sort[
"field"] = $kendoCol;
1998 $idName =
"reportId";
1999 $fieldData[$idName] = array(
"type" =>
"number");
2000 $modelData[
"id"] = $idName;
2001 $modelData[
"fields"] = $fieldData;
2002 }
catch(exception $e) {
2003 return array(
"error" => array($e->getMessage()),
"status" => $e->getCode(),
"gridConf" => array());
2005 return array(
"error" => array(),
"status" =>
"000",
"gridConf" => array(
"modelData" => $modelData,
"columnData" => $columnData,
"groupData" => $groupData,
"sort" => $sort));
2018 function RunCurl($parameters, $cmd, $cookieName) {
2019 $ch = curl_init($cmd);
2021 $cookieLine =
"HCUTicket=" . urlencode($_COOKIE[
'HCUTicket']) . ($cookieName !=
"" ?
";$cookieName=" . urlencode($_COOKIE[$cookieName]) :
"");
2023 curl_setopt($ch, CURLOPT_COOKIE, $cookieLine);
2024 curl_setopt($ch, CURLOPT_USERPWD,
"nobody:no1home");
2025 curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); #
get response as
string 2026 curl_setopt($ch, CURLOPT_POST,
true);
2027 curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
2028 curl_setopt($ch, CURLOPT_FOLLOWLOCATION,
true);
2029 curl_setopt($ch, CURLOPT_COOKIESESSION,
true );
2030 curl_setopt($ch, CURLOPT_COOKIEJAR,
"/home/homecu/tmp/reportCookie");
2031 curl_setopt($ch, CURLOPT_COOKIEFILE,
"/home/homecu/tmp/reportCookie");
2033 $rawresp = curl_exec($ch);
2049 function PrintCSVData($reportData, $report, $reportTitle, $reportList, $defaultDateFormat, $delimiter =
",") {
2050 $reportRecord = $reportList[$report];
2051 $reportName = $reportTitle !=
"" ? $reportTitle : (HCU_array_key_exists(
"title", $reportRecord) ? $reportRecord[
"title"] : trim($report));
2052 $kendoDateFormat = HCU_array_key_exists(
"dateFormat", $reportRecord) ? $reportRecord[
"dateFormat"] : (isset($defaultDateFormat) ? $defaultDateFormat :
"MM/dd/yyyy");
2053 $showOnCSV = HCU_array_key_exists(
"showOnCSV", $reportRecord) ? $reportRecord[
"showOnCSV"] : array();
2055 $groupBy = HCU_array_key_exists(
"groupBy", $reportRecord) ? trim($reportRecord[
"groupBy"]) :
"";
2056 $groupDescription = HCU_array_key_exists(
"groupDescription", $reportRecord) ? trim($reportRecord[
"groupDescription"]) :
"";
2061 $phpDateFormatArray = array(
"yyyy" =>
"Y",
"dd" =>
"d",
"HH" =>
"H",
"MM" =>
"m",
"mm" =>
"i",
"ss" =>
"s");
2062 $dateArray = array();
2063 $ignoreMap = array();
2064 $currencyMap = array();
2066 $unencodedMap = array();
2068 $phpDateFormat = $kendoDateFormat;
2069 foreach($phpDateFormatArray as $from => $to) {
2070 $phpDateFormat = str_replace($from, $to, $phpDateFormat);
2073 if ($groupBy !=
"") {
2076 foreach($reportRecord[
"cols"] as $colTitle => $colType) {
2077 $kendoCol = strtolower(GetCamelCase($colTitle));
2082 $dateArray[$kendoCol] =
true;
2085 $currencyMap[$kendoCol] =
true;
2088 $listMap[$kendoCol] = $reportRecord[
"ddl"][$colTitle];
2091 $unencodedMap[$kendoCol] =
true;
2096 $showColumnByGroup = $groupBy !=
"" ? ($groupDescription !=
"" ? $groupDescription == $colTitle : $groupBy == $colTitle) :
false;
2099 $ignoreColumn = HCU_array_key_exists($colTitle, $showOnCSV) ? !$showOnCSV[$colTitle] : ($showColumnByGroup ? false : in_array($colType, array(
"ignore",
"hidden")));
2100 $ignoreMap[$kendoCol] = $ignoreColumn;
2103 if ($colTitle == $groupBy || $colTitle == $groupDescription || $ignoreColumn) {
2107 $csvRow[] = getCsvValue(explode(
".", $colTitle)[0], $delimiter);
2110 $csvData[] = implode(
"$delimiter", $csvRow);
2112 if ($groupBy ==
"") {
2113 foreach($reportData as $row) {
2115 foreach($row as $col => $value) {
2116 $lcol = strtolower($col);
2117 if ($ignoreMap[$lcol]) {
2120 if (HCU_array_key_exists($lcol, $dateArray)) {
2122 if (isset($value) && trim($value) !=
"") {
2123 $dateTime =
new DateTime($value);
2124 $value = $dateTime->format($phpDateFormat);
2126 }
catch (exception $e) {
2127 $value =
"(Invalid Date Format)";
2129 }
else if (HCU_array_key_exists($lcol, $currencyMap)) {
2130 $value = intval($value) == 0 ?
"" :
"\$" . number_format(floatval($value), 2);
2131 }
else if (HCU_array_key_exists($lcol, $listMap)) {
2132 $value = $listMap[$lcol][trim($value)];
2133 }
else if (HCU_array_key_exists($lcol, $unencodedMap)) {
2134 $value = strip_tags($value);
2136 $value = strval($value);
2139 $csvRow[] = GetCsvValue($value, $delimiter);
2141 $csvData[] = implode(
"$delimiter", $csvRow);
2144 $groupByCol = strtolower(GetCamelCase($groupBy));
2145 $groupDescriptionCol = strtolower(GetCamelCase($groupDescription));
2147 foreach($reportData as $row) {
2152 if (!$ignoreMap[$groupByCol]) {
2153 $csvData[] = implode(
"$delimiter", array(GetCsvValue($groupBy, $delimiter), GetCsvValue($row[
"value"], $delimiter)));
2157 if ($groupDescription !=
"" && !$ignoreMap[$groupDescription]) {
2158 $descriptionValue = $row[
"aggregates"][GetCamelCase($groupDescription)][
"max"];
2160 if (!$ignoreMap[$groupDescriptionCol]) {
2161 $csvData[] = implode(
"$delimiter", array(GetCsvValue($groupDescription, $delimiter), GetCsvValue($descriptionValue, $delimiter)));
2167 foreach($row[
"items"] as $rowRow) {
2169 $csvRow = array(
"");
2170 foreach($rowRow as $col => $value) {
2171 $lower = strtolower($col);
2172 if ($lower == $groupByCol || $lower == $groupDescriptionCol || $ignoreMap[$lower]) {
2176 if (HCU_array_key_exists($lower, $dateArray)) {
2178 if (isset($value) && trim($value) !=
"") {
2179 $dateTime =
new DateTime($value);
2180 $value = $dateTime->format($phpDateFormat);
2183 }
catch (exception $e) {
2184 $value =
"(Invalid Date Format)";
2186 }
else if (HCU_array_key_exists($lower, $currencyMap)) {
2187 $value = intval($value) == 0 ?
"" :
"\$" . number_format(floatval($value), 2);
2188 }
else if (HCU_array_key_exists($lower, $listMap)) {
2189 $value = $listMap[$lower][trim($value)];
2190 }
else if (HCU_array_key_exists($lower, $unencodedMap)) {
2191 $value = strip_tags($value);
2193 $value = strval($value);
2196 $csvRow[] = GetCsvValue($value, $delimiter);
2198 $csvData[] = implode(
"$delimiter", $csvRow);
2203 $csvData = implode(
"\r\n", $csvData);
2205 header(
"Content-length: " . strlen($csvData) );
2206 header(
"Content-type: application/octetstream");
2207 header(
"Content-disposition: inline; filename=\"$reportName.csv\"");
2220 function GetCsvValue($value, $delimiter) {
2221 $value = str_replace(
" ",
" ", trim($value));
2222 if (strpos($value,
"$delimiter") !==
false || strpos($value,
"\n") !==
false) {
2223 $value =
"\"$value\"";
2234 function ValidateReportRecord($reportRecord) {
2235 if (!HCU_array_key_exists(
"sql", $reportRecord) && !HCU_array_key_exists(
"nonSqlDataFunc", $reportRecord)) {
2236 throw new exception(
"Either SQL or another way of getting the data is required.", 101);
2238 if (!HCU_array_key_exists(
"cols", $reportRecord)) {
2239 throw new exception(
"Cols are required.", 102);
2241 foreach($reportRecord[
"cols"] as $colName => $colType) {
2242 if (!in_array($colType, array(
"number",
"decimal",
"string",
"date",
"boolean",
"odata",
"currency",
"ignore",
"list",
"hidden",
"description",
"unencoded",
"datetime"))) {
2243 throw new exception(
"Column type is not known.", 103);
2245 if ($colType ==
"list") {
2246 if (!HCU_array_key_exists(
"ddl", $reportRecord)) {
2247 throw new exception (
"DDLs are not defined.", 104);
2249 if (!HCU_array_key_exists($colName, $reportRecord[
"ddl"])) {
2250 throw new exception (
"DDL is not defined for $colName.", 105);
GetColumnSQL($toBeSummed)