updated advanced pack to 3.12.0:

Reports:

    Non-aggregated columns in Grid report export.
    Normalized table mode for 2-dimensional Grid reports.
    Ability to create internal reports via the UI.
    Ability to show/hide and resize columns in the list report result view.
This commit is contained in:
2026-02-07 16:09:20 +01:00
parent 26db904407
commit f95246f99f
384 changed files with 6184 additions and 3643 deletions

View File

@@ -11,13 +11,14 @@
* usage to the software or any modified version or derivative work of the software
* created by or for you.
*
* Copyright (C) 2015-2025 EspoCRM, Inc.
* Copyright (C) 2015-2026 EspoCRM, Inc.
*
* License ID: 19bc86a68a7bb01f458cb391d43a9212
************************************************************************************/
namespace Espo\Modules\Advanced\Tools\Report;
use Espo\Core\Binding\BindingContainerBuilder;
use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Formula\Exceptions\Error as FormulaError;
@@ -53,19 +54,28 @@ class ReportHelper
private FormulaManager $formulaManager,
private Config $config,
private Preferences $preferences,
private FormulaChecker $formulaChecker
private FormulaChecker $formulaChecker,
) {}
/**
* @throws Error
* @return ListReport|GridReport
*/
public function createInternalReport(Report $report): object
public function createInternalReport(Report $report): ListReport|GridReport
{
$className = $report->get('internalClassName');
$name = $report->get('internalClassName');
if ($className && stripos($className, ':') !== false) {
[$moduleName, $reportName] = explode(':', $className);
if (!$name) {
throw new Error('Internal report name is not specified.');
}
$className = $this->metadata->get("app.advancedReport.internalReports.$name.className");
if (!$className) {
if (stripos($name, ':') === false) {
throw new Error("Internal report $name is not defined.");
}
[$moduleName, $reportName] = explode(':', $name);
if ($moduleName === 'Custom') {
$className = "Espo\\Custom\\Reports\\$reportName";
@@ -74,13 +84,17 @@ class ReportHelper
}
}
if (!$className) {
throw new Error('No class name specified for internal report.');
if (!class_exists($className)) {
throw new Error("Class $className for report $name does not exist.");
}
/** @var class-string<ListReport|GridReport> $className */
return $this->injectableFactory->create($className);
$binding = BindingContainerBuilder::create()
->bindInstance(Report::class, $report)
->build();
return $this->injectableFactory->createWithBinding($className, $binding);
}
/**
@@ -109,18 +123,19 @@ class ReportHelper
}
return new GridData(
$report->getTargetEntityType(),
$report->getColumns(),
$report->getGroupBy(),
$report->getOrderBy(),
$report->getApplyAcl(),
$this->fetchFiltersWhereFromReport($report),
$report->get('chartType'),
get_object_vars($report->get('chartColors') ?? (object) []),
$report->get('chartColor'),
$report->get('chartDataList'),
($report->get('data') ?? (object) [])->success ?? null,
$report->getColumnsData(),
entityType: $report->getTargetEntityType(),
columns: $report->getColumns(),
groupBy: $report->getGroupBy(),
orderBy: $report->getOrderBy(),
applyAcl: $report->getApplyAcl(),
filtersWhere: $this->fetchFiltersWhereFromReport($report),
chartType: $report->getChartType(),
chartColors: get_object_vars($report->get('chartColors') ?? (object) []),
chartColor: $report->get('chartColor'),
chartDataList: $report->get('chartDataList'),
success: ($report->get('data') ?? (object) [])->success ?? null,
columnsData: $report->getColumnsData(),
tableMode: $report->getTableMode(),
);
}