PHP Code:
<?php
namespace Espo\Modules\MyModule\Classes\Select\ComplianceReport\PrimaryFilters;
use Espo\{
Core\Select\Primary\Filter,
Modules\MyModule\Entities\ComplianceReport,
ORM\Query\Part\Expression,
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\Condition as Cond,
ORM\EntityManager,
Core\Utils\Log
};
class Latest implements Filter
{
private EntityManager $entityManager;
private Log $log;
public function __construct(EntityManager $entityManager, Log $log)
{
$this->entityManager = $entityManager;
$this->log = $log;
}
public function apply(QueryBuilder $queryBuilder): void
{
//we want to select the latest, non-deleted compliance report for each accountId
//the code below will ensure only 1 result comes back for each accountId even if createdAt
//is the same for two different compliance reports
//MYSQL EXAMPLE
//SELECT cr1.*
//FROM compliance_report AS cr1
//WHERE cr1.id IN(
// SELECT MAX(id)
// FROM compliance_report
// WHERE (cr1.account_id, cr1.created_at) IN(
// SELECT account_id, MAX(created_at)
// FROM compliance_report
// WHERE deleted = false
// GROUP BY account_id
// )
// GROUP BY account_id, created_at
//);
$subQuery1 = QueryBuilder::create()
->select(["accountId", "MAX:(createdAt)"])
->from(ComplianceReport::ENTITY_TYPE)
->where(["deleted" => false])
->group(["accountId"])
->build();
$subQuery2 = QueryBuilder::create()
->select("MAX:(id)")
->from(ComplianceReport::ENTITY_TYPE)
->where(
Cond::in(
Expression::row(
Expression::column("accountId"),
Expression::column("createdAt")
),
$subQuery1
)
)
->group(["accountId", "createdAt"])
->build();
//$sql2 = $this->entityManager->getQueryComposer()->compose($subQuery2);
//$this->log->warning('Latest.php ComplianceReport - apply() #55 $sql2= ', [$sql2]);
$queryBuilder->where([
"id=s" => $subQuery2,
]);
}
}
Leave a comment: