entityManager->getEntityById(Report::ENTITY_TYPE, $id); if (!$report) { throw new NotFound(); } if ($user && !$this->aclManager->checkEntityRead($user, $report)) { throw new Forbidden(); } $contents = $this->buildXlsxContents($id, $where, $user); $name = preg_replace("/([^\w\s\d\-_~,;:\[\]().])/u", '_', $report->getName()) . ' ' . date('Y-m-d'); $mimeType = $this->metadata->get(['app', 'export', 'formatDefs', 'xlsx', 'mimeType']); $fileExtension = $this->metadata->get(['app', 'export', 'formatDefs', 'xlsx', 'fileExtension']); $fileName = $name . '.' . $fileExtension; $attachment = $this->entityManager->getNewEntity(Attachment::ENTITY_TYPE); $attachment->set('name', $fileName); $attachment->set('role', 'Export File'); $attachment->set('type', $mimeType); $attachment->set('contents', $contents); $attachment->set([ 'relatedType' => Report::ENTITY_TYPE, 'relatedId' => $id, ]); $this->entityManager->saveEntity($attachment); return $attachment->getId(); } /** * @throws Error * @throws Forbidden * @throws NotFound * @throws Exception * @throws BadRequest */ public function buildXlsxContents(string $id, ?WhereItem $where, ?User $user = null): string { /** @var ?Report $report */ $report = $this->entityManager->getEntityById(Report::ENTITY_TYPE, $id); if (!$report) { throw new NotFound(); } $entityType = $report->getTargetEntityType(); $groupCount = count($report->getGroupBy()); $columnList = $report->getColumns(); $groupByList = $report->getGroupBy(); $reportResult = null; if ( $report->getType() === Report::TYPE_JOINT_GRID || !$report->getGroupBy() ) { $reportResult = $this->service->runGrid($id, $where, $user); $columnList = $reportResult->getColumnList(); $groupByList = $reportResult->getGroupByList(); $groupCount = count($groupByList); } if (!$reportResult) { $reportResult = $this->service->runGrid($id, $where, $user); } $result = []; if ($groupCount === 2) { foreach ($reportResult->getSummaryColumnList() as $column) { $result[] = $this->getGridReportResultForExport($id, $where, $column, $user, $reportResult); } } else { $result[] = $this->getGridReportResultForExport($id, $where, null, $user, $reportResult); } $columnTypes = []; foreach ($columnList as $item) { $columnData = $this->gridHelper->getDataFromColumnName($entityType, $item, $reportResult); $type = $this->metadata ->get(['entityDefs', $columnData->entityType, 'fields', $columnData->field, 'type']); if ( $entityType === Opportunity::ENTITY_TYPE && $columnData->field === 'amountWeightedConverted' ) { $type = 'currencyConverted'; } if ($columnData->function === 'COUNT') { $type = 'int'; } $columnTypes[$item] = $type; } $columnLabels = []; if ($groupCount === 2) { $columnNameMap = $reportResult->getColumnNameMap() ?? []; foreach ($columnList as $column) { $columnLabels[$column] = $columnNameMap[$column]; } } $exportParams = [ 'exportName' => $report->getName(), 'columnList' => $columnList, 'columnTypes' => $columnTypes, 'chartType' => $report->get('chartType'), 'groupByList' => $groupByList, 'columnLabels' => $columnLabels, 'reportResult' => $reportResult, 'groupLabel' => '', ]; if ($groupCount) { $group = $groupByList[$groupCount - 1]; $exportParams['groupLabel'] = $this->gridUtil->translateGroupName($entityType, $group); } $export = $this->injectableFactory->create(ExportXlsx::class); return $export->process($entityType, $exportParams, $result); } /** * @throws Forbidden * @throws NotFound * @throws Error */ public function exportCsv( string $id, ?WhereItem $where, ?string $column = null, ?User $user = null ): string { /** @var ?Report $report */ $report = $this->entityManager->getEntityById(Report::ENTITY_TYPE, $id); if (!$report) { throw new NotFound(); } if ($user && !$this->aclManager->checkEntityRead($user, $report)) { throw new Forbidden(); } $contents = $this->getGridReportCsv($id, $where, $column, $user); $name = preg_replace("/([^\w\s\d\-_~,;:\[\]().])/u", '_', $report->getName()) . ' ' . date('Y-m-d'); $mimeType = $this->metadata->get(['app', 'export', 'formatDefs', 'csv', 'mimeType']); $fileExtension = $this->metadata->get(['app', 'export', 'formatDefs', 'csv', 'fileExtension']); $fileName = $name . '.' . $fileExtension; $attachment = $this->entityManager->getEntity('Attachment'); $attachment->set('name', $fileName); $attachment->set('role', 'Export File'); $attachment->set('type', $mimeType); $attachment->set('contents', $contents); $attachment->set([ 'relatedType' => Report::ENTITY_TYPE, 'relatedId' => $id, ]); $this->entityManager->saveEntity($attachment); return $attachment->getId(); } /** * @throws Forbidden * @throws Error * @throws NotFound * @throws BadRequest */ private function getGridReportCsv( string $id, ?WhereItem $where, ?string $column = null, ?User $user = null ): string { $result = $this->getGridReportResultForExport($id, $where, $column, $user); $delimiter = $this->config->get('exportDelimiter', ';'); $fp = fopen('php://temp', 'w'); if ($fp === false) { throw new RuntimeException("Could not open temp."); } foreach ($result as $row) { fputcsv($fp, $row, $delimiter); } rewind($fp); $csv = stream_get_contents($fp); fclose($fp); if ($csv === false) { throw new RuntimeException("Could not get from stream."); } return $csv; } /** * @return array[] * @throws Error * @throws Forbidden * @throws NotFound * @throws BadRequest */ private function getGridReportResultForExport( string $id, ?WhereItem $where, ?string $currentColumn = null, ?User $user = null, ?GridResult $reportResult = null ): array { if (!$reportResult) { $reportResult = $this->service->runGrid($id, $where, $user); } $depth = count($reportResult->getGroupByList()); $reportData = $reportResult->getReportData(); $result = []; if ($depth == 2) { $groupName1 = $reportResult->getGroupByList()[0]; $groupName2 = $reportResult->getGroupByList()[1]; $group1NonSummaryColumnList = []; $group2NonSummaryColumnList = []; if ($reportResult->getGroup1NonSummaryColumnList() !== null) { $group1NonSummaryColumnList = $reportResult->getGroup1NonSummaryColumnList(); } if ($reportResult->getGroup2NonSummaryColumnList() !== null) { $group2NonSummaryColumnList = $reportResult->getGroup2NonSummaryColumnList(); } $row = []; $row[] = ''; foreach ($group2NonSummaryColumnList as $column) { $text = $reportResult->getColumnNameMap()[$column]; $row[] = $text; } foreach ($reportResult->getGrouping()[0] ?? [] as $gr1) { $label = $gr1; if (empty($label)) { $label = $this->language->translate('-Empty-', 'labels', 'Report'); } else if (!empty($reportResult->getGroupValueMap()[$groupName1][$gr1])) { $label = $reportResult->getGroupValueMap()[$groupName1][$gr1]; } $row[] = $label; } $result[] = $row; foreach ($reportResult->getGrouping()[1] ?? [] as $gr2) { $row = []; $label = $gr2; if (empty($label)) { $label = $this->language->translate('-Empty-', 'labels', 'Report'); } else if (!empty($reportResult->getGroupValueMap()[$groupName2][$gr2])) { $label = $reportResult->getGroupValueMap()[$groupName2][$gr2]; } $row[] = $label; foreach ($group2NonSummaryColumnList as $column) { $row[] = $this->getCellDisplayValueFromResult(1, $gr2, $column, $reportResult); } foreach ($reportResult->getGrouping()[0] ?? [] as $gr1) { $value = 0; if (!empty($reportData->$gr1) && !empty($reportData->$gr1->$gr2)) { if (!empty($reportData->$gr1->$gr2->$currentColumn)) { $value = $reportData->$gr1->$gr2->$currentColumn; } } $row[] = $value; } $result[] = $row; } $row = []; $row[] = $this->language->translate('Total', 'labels', 'Report'); foreach ($group2NonSummaryColumnList as $ignored) { $row[] = ''; } foreach ($reportResult->getGrouping()[0] ?? [] as $gr1) { $sum = 0; if (!empty($reportResult->getGroup1Sums()->$gr1)) { if (!empty($reportResult->getGroup1Sums()->$gr1->$currentColumn)) { $sum = $reportResult->getGroup1Sums()->$gr1->$currentColumn; } } $row[] = $sum; } $result[] = $row; if (count($group1NonSummaryColumnList)) { $result[] = []; } foreach ($group1NonSummaryColumnList as $column) { $row = []; $text = $reportResult->getColumnNameMap()[$column]; $row[] = $text; foreach ($group2NonSummaryColumnList as $ignored) { $row[] = ''; } foreach ($reportResult->getGrouping()[0] ?? [] as $gr1) { $row[] = $this->getCellDisplayValueFromResult(0, $gr1, $column, $reportResult); } $result[] = $row; } } else if ($depth === 1 || $depth === 0) { $aggregatedColumnList = $reportResult->getAggregatedColumnList(); if ($depth === 1) { $groupName = $reportResult->getGroupByList()[0]; } else { $groupName = self::STUB_KEY; } $row = []; $row[] = ''; foreach ($aggregatedColumnList as $column) { $label = $column; if (!empty($reportResult->getColumnNameMap()[$column])) { $label = $reportResult->getColumnNameMap()[$column]; } $row[] = $label; } $result[] = $row; foreach ($reportResult->getGrouping()[0] ?? [] as $gr) { $row = []; $label = $gr; if (empty($label)) { $label = $this->language->translate('-Empty-', 'labels', 'Report'); } else if ( !empty($reportResult->getGroupValueMap()[$groupName]) && array_key_exists($gr, $reportResult->getGroupValueMap()[$groupName]) ) { $label = $reportResult->getGroupValueMap()[$groupName][$gr]; } $row[] = $label; foreach ($aggregatedColumnList as $column) { if (in_array($column, $reportResult->getNumericColumnList())) { $value = 0; if (!empty($reportData->$gr)) { if (!empty($reportData->$gr->$column)) { $value = $reportData->$gr->$column; } } } else { $value = ''; if (property_exists($reportData, $gr) && property_exists($reportData->$gr, $column)) { $value = $reportData->$gr->$column; if ( !is_null($value) && property_exists($reportResult->getCellValueMaps(), $column) && property_exists($reportResult->getCellValueMaps()->$column, $value) ) { $value = $reportResult->getCellValueMaps()->$column->$value; } } } $row[] = $value; } $result[] = $row; } if ($depth) { $row = []; $row[] = $this->language->translate('Total', 'labels', 'Report'); foreach ($aggregatedColumnList as $column) { if (!in_array($column, $reportResult->getNumericColumnList())) { $row[] = ''; continue; } $sum = 0; if (!empty($reportResult->getSums()->$column)) { $sum = $reportResult->getSums()->$column; } $row[] = $sum; } $result[] = $row; } } return $result; } /** * @return mixed */ public function getCellDisplayValueFromResult( int $groupIndex, string $gr1, string $column, GridResult $reportResult ) { $groupName = $reportResult->getGroupByList()[$groupIndex]; $dataMap = $reportResult->getNonSummaryData()->$groupName; $value = ''; if ($this->gridHelper->isColumnNumeric($column, $reportResult)) { $value = 0; } if ( property_exists($dataMap, $gr1) && property_exists($dataMap->$gr1, $column) ) { $value = $dataMap->$gr1->$column; } if ( !$this->gridHelper->isColumnNumeric($column, $reportResult) && !is_null($value) ) { if (property_exists($reportResult->getCellValueMaps(), $column)) { if (property_exists($reportResult->getCellValueMaps()->$column, $value)) { $value = $reportResult->getCellValueMaps()->$column->$value; } } } if (is_null($value)) { $value = ''; } return $value; } /** * @throws Forbidden * @throws Error * @throws NotFound */ public function exportPdf( string $id, ?WhereItem $where, string $templateId, ?User $user = null ): string { $report = $this->entityManager->getEntityById(Report::ENTITY_TYPE, $id); $template = $this->entityManager->getEntityById(Template::ENTITY_TYPE, $templateId); if (!$report || !$template) { throw new NotFound(); } if ($user) { if (!$this->aclManager->checkEntityRead($user, $report)) { throw new Forbidden("No access to report."); } if (!$this->aclManager->checkEntityRead($user, $template)) { throw new Forbidden("No access to template."); } } $additionalData = [ 'user' => $user, 'reportWhere' => $where, ]; $pdfService = $this->injectableFactory->create(PdfService::class); $contents = $pdfService ->generate( Report::ENTITY_TYPE, $report->getId(), $template->getId(), null, Data::create()->withAdditionalTemplateData((object) $additionalData) ) ->getString(); $attachment = $this->entityManager->createEntity(Attachment::ENTITY_TYPE, [ 'contents' => $contents, 'role' => 'Export File', 'type' => 'application/pdf', 'relatedId' => $id, 'relatedType' => Report::ENTITY_TYPE, ]); return $attachment->getId(); } }