CakePHP3 如何让所有客户及其所有有效合同都有到期的报表

CakePHP3 How to get all Clients with all their active Contracts what have Statements due

我的客户有很多合同,其中有很多声明。

我想让所有客户的有效合同 (Contracts.published = 1) 有到期的报表 (Statements.periodend <= 2019-09-30 和 Statements.amount !=空)。

因此,如果没有有效合同或合同项下没有到期的报表,我不想让客户出现在结果集中。

这样我就可以遍历客户端并针对到期报表发送提醒电子邮件。

我编译了以下查询;

$query = $this->Statements->Contracts->Clients->find();$query
    ->matching('Contracts', function ($q) {
        return $q->where(['Contracts.published'=>true]);
    })
    ->contain('Contracts.Statements', function ($q) use ($date) {
        return $q
            ->where(['amount IS'=>NULL])
            ->where(['Statements.periodend <=' => '2019-09-30'])
            ->order(['periodend'=>'ASC']);
    })
    ->order(['Clients.name'=>'ASC']);

现在它正在返回所有客户的所有合同。

没有有效合同的客户将被忽略。

但我还想删除没有到期的 contracts/clients。

嵌套 contains with innerjoins 并添加一些 distinct 是问题的解决方案;

$date = '2019-12-31';

$clients = $this->Statements->Contracts->Clients->find()
        ->contain('Contracts', function ($q) use ($date) {
            return $q
                ->innerJoinWith('Statements', function ($q) use ($date){
                    return $q
                        ->where(['Statements.amount IS' => NULL])
                        ->where(['Statements.periodend <=' => $date]);
                })
                ->where(['Contracts.published' => true])
                ->contain('Statements', function ($q) use ($date) {
                    return $q
                        ->where(['Statements.amount IS' => NULL])
                        ->where(['Statements.periodend <=' => $date])
                        ->order(['Statements.periodend' => 'ASC']);
                })
                ->distinct(['Contracts.id']);
        })
        ->innerJoinWith('Contracts.Statements', function ($q) use ($date) {
            return $q
                ->where(['Statements.amount IS' => NULL])
                ->where(['Statements.periodend <=' => $date]);
        })
        ->distinct(['Clients.id']);