entityManager = $entityManager; $this->reportHelper = $reportHelper; $this->gridHelper = $gridHelper; $this->resultHelper = $resultHelper; $this->language = $language; $this->gridUtil = $gridUtil; $this->service = $service; } /** * @param ?array $idWhereMap * @throws Error * @throws Forbidden */ public function execute( JointData $data, ?User $user = null, ?array $idWhereMap = null ): GridResult { if ($data->getJoinedReportDataList() === []) { throw new Error("Bad report."); } $result = null; $groupColumn = null; $reportList = []; $groupCount = null; foreach ($data->getJoinedReportDataList() as $item) { if (empty($item->id)) { throw new Error("Bad report."); } /** @var ?Report $report */ $report = $this->entityManager->getEntity(Report::ENTITY_TYPE, $item->id); if (!$report) { throw new Error("Sub-report $item->id doesn't exist."); } $reportList[] = $report; } foreach ($data->getJoinedReportDataList() as $i => $item) { $report = $reportList[$i]; $where = null; if ($idWhereMap && isset($idWhereMap[$item->id])) { $where = $idWhereMap[$item->id]; } if ($report->isInternal()) { $reportObj = $this->reportHelper->createInternalReport($report); if (!$reportObj instanceof GridReport) { throw new Error("Bad report class."); } $subReportResult = $reportObj->run($where, $user); } else { if ($report->getType() !== Report::TYPE_GRID) { throw new Error("Bad sub-report."); } $this->reportHelper->checkReportCanBeRun($report); $subReportResult = $this->service->executeGridReport( $this->reportHelper->fetchGridDataFromReport($report), $where, $user ); } $subReportNumericColumnList = $subReportResult->getNumericColumnList(); $subReportAggregatedColumnList = $subReportResult->getAggregatedColumnList(); $subReportResult->setColumnOriginalMap([]); $subReportResult->setNumericColumnList([]); $subReportResult->setAggregatedColumnList([]); $columnToUnsetList = []; $columnOriginalMap = $subReportResult->getColumnOriginalMap(); $subReportColumnList = $subReportResult->getColumnList(); foreach ($subReportColumnList as &$columnPointer) { $originalColumnName = $columnPointer; $newColumnName = $columnPointer . '@'. $i; $columnOriginalMap[$newColumnName] = $columnPointer; if (in_array($originalColumnName, $subReportNumericColumnList)) { $subReportResult->setNumericColumnList( array_merge( $subReportResult->getNumericColumnList(), [$newColumnName] ) ); } if ( $subReportAggregatedColumnList && in_array($originalColumnName, $subReportAggregatedColumnList) ) { $subReportResult->setAggregatedColumnList( array_merge( $subReportResult->getAggregatedColumnList(), [$newColumnName] ) ); } if (!in_array($columnPointer, $subReportAggregatedColumnList)) { $columnToUnsetList[] = $newColumnName; } $columnPointer = $newColumnName; } $subReportColumnList = array_values(array_filter( $subReportColumnList, function (string $item) use ($columnToUnsetList) { return !in_array($item, $columnToUnsetList); } )); $subReportResult->setColumnList($subReportColumnList); $subReportResult->setColumnOriginalMap($columnOriginalMap); $sums = []; foreach (get_object_vars($subReportResult->getSums()) as $key => $sum) { $sums[$key . '@'. $i] = $sum; } $subReportResult->setSums((object) $sums); $columnNameMap = []; foreach ($subReportResult->getColumnNameMap() as $key => $name) { if (!str_contains($key, '.')) { if (!empty($item->label)) { $name = $item->label . ' ยท ' . $name; } } $columnNameMap[$key . '@'. $i] = $name; } $subReportResult->setColumnNameMap($columnNameMap); $columnTypeMap = []; foreach ($subReportResult->getColumnTypeMap() as $key => $type) { $columnTypeMap[$key . '@'. $i] = $type; } $subReportResult->setColumnTypeMap($columnTypeMap); $columnDecimalPlacesMap = []; foreach (get_object_vars($subReportResult->getColumnDecimalPlacesMap()) as $key => $type) { $columnDecimalPlacesMap[$key . '@'. $i] = $type; } $subReportResult->setColumnDecimalPlacesMap((object) $columnDecimalPlacesMap); $chartColors = []; if ($subReportResult->getChartColor()) { $chartColors[$subReportResult->getColumnList()[0]] = $subReportResult->getChartColor(); } foreach (get_object_vars($subReportResult->getChartColors()) as $key => $color) { $chartColors[$key . '@'. $i] = $color; } $subReportResult->setChartColors((object) $chartColors); $cellValueMaps = (object) []; foreach (get_object_vars($subReportResult->getCellValueMaps()) as $column => $map) { $cellValueMaps->{$column . '@'. $i} = $map; } $subReportResult->setCellValueMaps($cellValueMaps); $reportData = $subReportResult->getReportData(); foreach (get_object_vars($subReportResult->getReportData()) as $key => $dataItem) { $newDataItem = (object) []; foreach (get_object_vars($dataItem) as $key1 => $value) { $newDataItem->{$key1 . '@'. $i} = $value; } $reportData->$key = $newDataItem; } $subReportResult->setReportData($reportData); if ($i === 0) { $groupCount = count($report->getGroupBy()); if ($groupCount) { $groupColumn = $report->getGroupBy()[0]; } if ($groupCount > 2) { throw new Error("Grouping by 2 columns is not supported in joint reports."); } $result = $subReportResult; $result->setEntityTypeList([$report->getTargetEntityType()]); $result->setColumnEntityTypeMap([]); $result->setColumnReportIdMap([]); $result->setColumnSubReportLabelMap([]); } else { if ($groupCount === null) { throw new LogicException(); } if (count($report->getGroupBy()) !== $groupCount) { throw new Error("Sub-reports must have the same Group By number."); } foreach ($subReportResult->getColumnList() as $column) { $columnList = $result->getColumnList(); $columnList[] = $column; $result->setColumnList($columnList); } foreach (get_object_vars($subReportResult->getSums()) as $key => $value) { $sums = $result->getSums(); $sums->$key = $value; $result->setSums($sums); } foreach ($subReportResult->getColumnNameMap() as $key => $name) { $map = $result->getColumnNameMap(); $map[$key] = $name; $result->setColumnNameMap($map); } foreach (($subReportResult->getColumnTypeMap() ?? []) as $key => $type) { $map = $result->getColumnTypeMap(); $map[$key] = $type; $result->setColumnTypeMap($map); } foreach (get_object_vars($subReportResult->getChartColors()) as $key => $value) { $map = $result->getChartColors(); $map->$key = $value; $result->setChartColors($map); } foreach ($subReportResult->getColumnOriginalMap() as $key => $value) { $map = $result->getColumnOriginalMap(); $map[$key] = $value; $result->setColumnOriginalMap($map); } foreach (get_object_vars($subReportResult->getCellValueMaps()) as $column => $value) { $map = $result->getCellValueMaps(); $map->$column = $value; $result->setCellValueMaps($map); } foreach ($subReportResult->getGroupValueMap() as $group => $v) { $map = $result->getGroupValueMap(); if (!array_key_exists($group, $map)) { continue; } $map[$group] = array_replace($map[$group], $v); $result->setGroupValueMap($map); } foreach ($subReportResult->getNumericColumnList() as $item1) { $list = $result->getNumericColumnList(); $list[] = $item1; $result->setNumericColumnList($list); } foreach ($subReportResult->getAggregatedColumnList() as $item1) { $list = $result->getAggregatedColumnList(); $list[] = $item1; $result->setAggregatedColumnList($list); } foreach (($subReportResult->getGrouping()[0] ?? []) as $groupName) { if (in_array($groupName, $result->getGrouping()[0] ?? [])) { continue; } $list = $result->getGrouping()[0] ?? []; $list[] = $groupName; $result->setGrouping([$list]); } foreach (get_object_vars($subReportResult->getReportData()) as $key => $dataItem) { $reportData = $result->getReportData(); if (property_exists($reportData, $key)) { foreach (get_object_vars($dataItem) as $key1 => $value) { $reportData->$key->$key1 = $value; } } else { $reportData->$key = $dataItem; } $result->setReportData($reportData); } $entityTypeList = $result->getEntityTypeList() ?? []; $entityTypeList[] = $report->getTargetEntityType(); $result->setEntityTypeList($entityTypeList); } foreach ($subReportResult->getColumnList() as $column) { $columnEntityTypeMap = $result->getColumnEntityTypeMap(); $columnReportIdMap = $result->getColumnReportIdMap(); $columnSubReportLabelMap = $result->getColumnSubReportLabelMap(); $columnEntityTypeMap[$column] = $report->getTargetEntityType(); $columnReportIdMap[$column] = $report->getId(); $columnSubReportLabelMap[$column] = !empty($item->label) ? $item->label : $this->language->translateLabel($report->getTargetEntityType(), 'scopeNamesPlural'); $result->setColumnEntityTypeMap($columnEntityTypeMap); $result->setColumnReportIdMap($columnReportIdMap); $result->setColumnSubReportLabelMap($columnSubReportLabelMap); } } if ( $groupColumn && isset($result->getGrouping()[0]) ) { $list = $result->getGrouping()[0]; $this->resultHelper->prepareGroupingRange($groupColumn, $list); $result->setGrouping([$list]); } foreach (get_object_vars($result->getReportData()) as $key => $dataItem) { foreach ($result->getColumnList() as $column) { if (property_exists($dataItem, $column)) { continue; } $originalColumn = $result->getColumnOriginalMap()[$column]; $originalEntityType = $result->getColumnEntityTypeMap()[$column]; [, $i] = explode('@', $column); $i = (int) $i; $report = $reportList[$i]; $gridData = $this->reportHelper->fetchGridDataFromReport($report); $reportData = $result->getReportData(); if ($this->gridHelper->isColumnNumeric($originalColumn, $gridData)) { $reportData->$key->$column = 0; continue; } $value = null; if ($groupColumn && $groupColumn !== self::STUB_KEY) { $subReportGroupColumn = $report->getGroupBy()[0]; if (str_starts_with($originalColumn, $subReportGroupColumn)) { $displayValue = null; $columnData = $this->gridHelper->getDataFromColumnName($originalEntityType, $originalColumn); $e = $this->entityManager->getEntity($columnData->entityType, $key); if ($e) { $value = $e->get($columnData->field); if ($columnData->fieldType === 'link') { $value = $e->get($columnData->field . 'Id'); $displayValue = $e->get($columnData->field . 'Name'); } else { $displayValue = $this->gridUtil->getCellDisplayValue($value, $columnData); } } if (!is_null($displayValue)) { $maps = $result->getCellValueMaps(); if (!property_exists($maps, $column)) { $maps->$column = (object) []; } $maps->$column->$value = $displayValue; $result->setCellValueMaps($maps); } } } $reportData->$key->$column = $value; $result->setReportData($reportData); } } $this->setSummaryColumnList($result, $reportList); $result->setSubListColumnList([]); $result->setChartType($data->getChartType()); $result->setIsJoint(true); $this->setChartColors($result); $this->setChartDataList($reportList, $result); return $result; } /** * @param Report[] $reportList */ private function setChartDataList(array $reportList, GridResult $result): void { $chartColumnList = []; $chartY2ColumnList = []; foreach ($reportList as $i => $report) { $gridData = $this->reportHelper->fetchGridDataFromReport($report); $itemDataList = $gridData->getChartDataList(); if ($itemDataList && count($itemDataList)) { foreach ($itemDataList[0]->columnList ?? [] as $item) { $chartColumnList[] = $item . '@' . $i; } foreach ($itemDataList[0]->y2ColumnList ?? [] as $item) { $chartY2ColumnList[] = $item . '@' . $i; } } } if ($chartColumnList === [] && $chartY2ColumnList === []) { return; } $result->setChartDataList([ (object) [ 'columnList' => $chartColumnList, 'y2ColumnList' => $chartY2ColumnList, ] ]); } private function setChartColors(GridResult $result): void { $colorList = []; $chartColors = $result->getChartColors(); foreach (get_object_vars($chartColors) as $key => $value) { if (in_array($value, $colorList)) { unset($chartColors->$key); } $colorList[] = $value; } if (array_keys(get_object_vars($chartColors)) === []) { $chartColors = null; } $result->setChartColors($chartColors); } /** * @param Report[] $reportList */ private function setSummaryColumnList(GridResult $result, array $reportList): void { $summaryColumnList = []; foreach ($result->getColumnList() as $column) { [, $i] = explode('@', $column); $report = $reportList[$i]; $gridData = $this->reportHelper->fetchGridDataFromReport($report); if ($this->gridHelper->isColumnSummary($column, $gridData)) { $summaryColumnList[] = $column; } } $result->setSummaryColumnList($summaryColumnList); } }