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:
@@ -11,7 +11,7 @@
|
||||
* 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
|
||||
************************************************************************************/
|
||||
@@ -20,8 +20,13 @@ namespace Espo\Modules\Advanced\Tools\Report;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Espo\Core\Binding\BindingContainerBuilder;
|
||||
use Espo\Core\Binding\ContextualBinder;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Select\Applier\AdditionalApplier;
|
||||
use Espo\Core\Select\SearchParams;
|
||||
use Espo\Core\Select\Where\Converter;
|
||||
use Espo\Core\Select\Where\ConverterFactory;
|
||||
use Espo\Core\Select\Where\Item as WhereItem;
|
||||
@@ -58,7 +63,8 @@ class SelectHelper
|
||||
private GridHelper $gridHelper,
|
||||
private FieldUtil $fieldUtil,
|
||||
private User $user,
|
||||
private ConverterFactory $converterFactory
|
||||
private ConverterFactory $converterFactory,
|
||||
private InjectableFactory $injectableFactory,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -415,8 +421,9 @@ class SelectHelper
|
||||
|
||||
/**
|
||||
* @param string[] $columns
|
||||
* @param bool $isList Should be true only for List report. Should not be true for Sub-List.
|
||||
*/
|
||||
public function handleColumns(array $columns, SelectBuilder $queryBuilder): void
|
||||
public function handleColumns(array $columns, SelectBuilder $queryBuilder, bool $isList = false): void
|
||||
{
|
||||
$entityType = $queryBuilder->build()->getFrom();
|
||||
|
||||
@@ -425,21 +432,24 @@ class SelectHelper
|
||||
}
|
||||
|
||||
foreach ($columns as $item) {
|
||||
$this->handleColumnsItem($item, $entityType, $queryBuilder);
|
||||
$this->handleColumnsItem($item, $entityType, $queryBuilder, $isList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Use the selectDefs attribute dependency map.
|
||||
* @todo Use the selectDefs attribute dependency map? Or not needed as already applied with the select manager.
|
||||
*/
|
||||
private function handleColumnsItem(
|
||||
string $item,
|
||||
string $entityType,
|
||||
SelectBuilder $queryBuilder
|
||||
SelectBuilder $queryBuilder,
|
||||
bool $isList = false,
|
||||
): void {
|
||||
|
||||
$columnData = $this->gridHelper->getDataFromColumnName($entityType, $item);
|
||||
|
||||
$entityDefs = $this->entityManager->getDefs()->getEntity($entityType);
|
||||
|
||||
if ($columnData->function && !$columnData->link && $columnData->field) {
|
||||
$this->addSelect($item, $queryBuilder);
|
||||
|
||||
@@ -460,6 +470,10 @@ class SelectHelper
|
||||
return;
|
||||
}
|
||||
|
||||
if ($isList) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (str_contains($item, ':') && str_contains($item, '.')) {
|
||||
$this->handleLeftJoins($item, $entityType, $queryBuilder);
|
||||
}
|
||||
@@ -486,8 +500,11 @@ class SelectHelper
|
||||
|
||||
if ($type === 'currency') {
|
||||
$this->addSelect($item, $queryBuilder);
|
||||
$this->addSelect($item . 'Currency', $queryBuilder);
|
||||
$this->addSelect($item . 'Converted', $queryBuilder);
|
||||
|
||||
if (!$entityDefs->tryGetField($item)?->getParam('notStorable')) {
|
||||
$this->addSelect($item . 'Currency', $queryBuilder);
|
||||
$this->addSelect($item . 'Converted', $queryBuilder);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -695,6 +712,8 @@ class SelectHelper
|
||||
throw new LogicException("No from.");
|
||||
}
|
||||
|
||||
$this->applyWhereFilterAdditionalAppliers($entityType, $whereItem, $queryBuilder);
|
||||
|
||||
// Supposed to be applied by the scanner.
|
||||
//$this->applyLeftJoinsFromWhere($whereItem, $queryBuilder);
|
||||
|
||||
@@ -886,4 +905,47 @@ class SelectHelper
|
||||
{
|
||||
return $this->converterFactory->create($entityType, $this->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string<AdditionalApplier>[]
|
||||
*/
|
||||
private function getWhereFiltersApplierClassNameList(string $entityType): array
|
||||
{
|
||||
/** @var class-string<AdditionalApplier>[] */
|
||||
return $this->metadata
|
||||
->get("app.advancedReport.entityParams.$entityType.whereFilterAdditionalApplierClassNameList") ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<AdditionalApplier> $className
|
||||
*/
|
||||
private function createAdditionalApplier(string $entityType, string $className): AdditionalApplier
|
||||
{
|
||||
return $this->injectableFactory->createWithBinding(
|
||||
$className,
|
||||
BindingContainerBuilder::create()
|
||||
->bindInstance(User::class, $this->user)
|
||||
->inContext($className, function (ContextualBinder $binder) use ($entityType) {
|
||||
$binder->bindValue('$entityType', $entityType);
|
||||
})
|
||||
->build()
|
||||
);
|
||||
}
|
||||
|
||||
private function applyWhereFilterAdditionalAppliers(
|
||||
string $entityType,
|
||||
WhereItem $whereItem,
|
||||
SelectBuilder $queryBuilder,
|
||||
): void {
|
||||
|
||||
$additionalApplierClassNameList = $this->getWhereFiltersApplierClassNameList($entityType);
|
||||
|
||||
foreach ($additionalApplierClassNameList as $className) {
|
||||
$applier = $this->createAdditionalApplier($entityType, $className);
|
||||
|
||||
$searchParams = SearchParams::create()->withWhere($whereItem);
|
||||
|
||||
$applier->apply($queryBuilder, $searchParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user