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,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
************************************************************************************/
@@ -26,7 +26,9 @@ use Espo\Core\Select\SelectBuilderFactory;
use Espo\Core\Select\Where\Item as WhereItem;
use Espo\Core\Utils\Language;
use Espo\Core\Utils\Metadata;
use Espo\Entities\Team;
use Espo\Entities\User;
use Espo\Modules\Advanced\Entities\Report;
use Espo\Modules\Advanced\Tools\Report\GridType\Result;
use Espo\Modules\Advanced\Tools\Report\ListType\Result as ListResult;
use Espo\Modules\Advanced\Tools\Report\ListType\SubReportParams;
@@ -34,6 +36,7 @@ use Espo\Modules\Crm\Entities\Call;
use Espo\Modules\Crm\Entities\Lead;
use Espo\Modules\Crm\Entities\Meeting;
use Espo\ORM\EntityManager;
use Espo\ORM\Name\Attribute;
use Espo\ORM\Query\Part\Condition as C;
use Espo\ORM\Query\Part\Expression as E;
use Espo\ORM\Query\Part\Order;
@@ -41,6 +44,9 @@ use Espo\ORM\Query\Part\WhereItem as WherePart;
use Espo\ORM\Query\SelectBuilder;
use RuntimeException;
/**
* @noinspection PhpUnused
*/
class LeadsByLastActivity implements GridReport
{
/** @var array<int, ?array{int, ?int}> */
@@ -61,17 +67,16 @@ class LeadsByLastActivity implements GridReport
private EntityManager $entityManager,
private Metadata $metadata,
private Language $language,
private SelectBuilderFactory $selectBuilderFactory
private SelectBuilderFactory $selectBuilderFactory,
private Report $report,
) {
$this->ignoreStatusList = $this->metadata
->get(['entityDefs', 'Lead', 'fields', 'status', 'notActualOptions']) ?? [];
$this->ignoreStatusList = $this->metadata->get("entityDefs.Lead.fields.status.notActualOptions") ?? [];
}
private function executeSubReport(
SearchParams $searchParams,
SubReportParams $subReportParams,
?User $user
?User $user,
): ListResult {
/** @var string $groupValue */
@@ -129,6 +134,8 @@ class LeadsByLastActivity implements GridReport
$queryBuilder->where(['status' => $groupValue]);
}
$this->applyTeamFilter($queryBuilder);
$query = $queryBuilder->build();
$collection = $this->entityManager
@@ -146,7 +153,6 @@ class LeadsByLastActivity implements GridReport
public function runSubReport(SearchParams $searchParams, SubReportParams $subReportParams, ?User $user): ListResult
{
return $this->executeSubReport($searchParams, $subReportParams, $user);
}
@@ -184,7 +190,7 @@ class LeadsByLastActivity implements GridReport
}
$columnNameMap = [
'COUNT:id' => $this->language->translateLabel('COUNT', 'functions', 'Report')
'COUNT:id' => $this->language->translateLabel('COUNT', 'functions', 'Report'),
];
$groupValueMap = [
@@ -233,25 +239,22 @@ class LeadsByLastActivity implements GridReport
$reportData = (object) $reportData;
$result = new Result(
Lead::ENTITY_TYPE,
$groupBy,
$columns,
$columns,
$columns,
[],
[],
[],
null,
null,
$sums,
$groupValueMap,
$columnNameMap,
[],
null,
$grouping,
$reportData,
null,
null
entityType: Lead::ENTITY_TYPE,
groupByList: $groupBy,
columnList: $columns,
numericColumnList: $columns,
summaryColumnList: $columns,
nonSummaryColumnList: [],
subListColumnList: [],
aggregatedColumnList: [],
sums: $sums,
groupValueMap: $groupValueMap,
columnNameMap: $columnNameMap,
columnTypeMap: [],
grouping: $grouping,
reportData: $reportData,
chartType: 'BarVertical',
noSubReport: false,
);
$result->setGroup1Sums((object) $group1Sums);
@@ -374,7 +377,7 @@ class LeadsByLastActivity implements GridReport
if (!$range[1]) {
$day = DateTime::createNow()
->addDays(- $range[0])
->getString();
->toString();
return C::or(
C::and(
@@ -390,11 +393,11 @@ class LeadsByLastActivity implements GridReport
$day1 = DateTime::createNow()
->addDays(- $range[0])
->getString();
->toString();
$day2 = DateTime::createNow()
->addDays(- $range[1])
->getString();
->toString();
return C::or(
C::and(
@@ -420,7 +423,7 @@ class LeadsByLastActivity implements GridReport
foreach ($this->rangeList as $i => $range) {
$where = $this->getWherePart($range);
$query = SelectBuilder::create()
$queryBuilder = SelectBuilder::create()
->from(Lead::ENTITY_TYPE)
->select(
E::count(E::column('id')),
@@ -429,8 +432,11 @@ class LeadsByLastActivity implements GridReport
->select('status')
->where(['status!=' => $this->ignoreStatusList])
->where($where)
->group('status')
->build();
->group('status');
$this->applyTeamFilter($queryBuilder);
$query = $queryBuilder->build();
$sth = $this->entityManager->getQueryExecutor()->execute($query);
@@ -452,4 +458,33 @@ class LeadsByLastActivity implements GridReport
return $resultData;
}
private function getFilterTeamId(): ?string
{
return $this->report->getInternalParams()->teamId ?? null;
}
private function applyTeamFilter(SelectBuilder $queryBuilder): void
{
$teamId = $this->getFilterTeamId();
if (!$teamId) {
return;
}
$queryBuilder->where(
C::in(
E::column(Attribute::ID),
SelectBuilder::create()
->select('entityId')
->from(Team::RELATIONSHIP_ENTITY_TEAM)
->where([
'entityType' => Lead::ENTITY_TYPE,
'teamId' => $teamId,
'deleted' => false,
])
->build()
)
);
}
}