如何使用Laravel的Eloquent

时间:2017-02-21 12:03:36

标签: laravel-5 datatables eloquent

我正在使用jQuery datatables插件并使用foreach循环添加列valores_receber(values_to_receive),这些循环执行总和但是以下面的代码中可以看到的单独方式。

public function anyDataReceber() {

$clientes = Partner::whereHas('faturamentos', function($q){
        $q->where('status', '<>', 'CANCELADO');
    })
    ->orWhereHas('faturamentosLivres', function ($q) {
        $q->where('status','<>','CANCELADO');
    })
    ->with('faturamentos')
    ->with('faturamentosLivres');

return Datatables::of($clientes)
    ->addColumn('valores_receber', function ($clientes) {
        $total = 0;
        foreach($clientes->faturamentos as $fatura1) {
            if ($fatura1->status != 'CANCELADO') $total += $fatura1->total_usd - $fatura1->valor_pago;
        }
        foreach($clientes->faturamentosLivres as $fatura2) {
            if ($fatura2->status != 'CANCELADO') $total += $fatura2->total_usd - $fatura2->valor_pago;
        }
        return number_format($total,2,',','.');
    })
    ->addColumn('action', function ($clientes) {
        $actions = '';
        $actions = '<a href="/admin/financeiro-matriz/contas-receber/'.$clientes->id.'" class="btn btn-xs btn-primary"><i class="fa fa-eye"></i> Visualizar</a>';
        return $actions;
    })
    ->make(true);

}

这里的问题是数据表无法对列valores_receber进行排序,因为Eloquent的结果查询中不存在此列。

我研究了mySQL中的SUM()函数,但我无法使用Eloquent和表关系来构建解决方案。

我检查了以下答案,这些答案应该在正确的轨道上,但是使用的是普通的SQL而且从我研究的它需要某种连接或联合语句,但是如何在Eloquent中执行它?

因此,要使数据表能够对列valores_receber进行排序,我需要该列显示在某种Eloquent语句的结果中。

我想要实现的目标是:

  • 使用Eloquent进行查询,该查询将两个表faturamentos和faturamentos_livres(发票和free_invoices)中存在的total_usd列的值相加
  • 这些表需要由状态列限制,该列必须是任何值,但CANCELADO(已取消)。此状态列是ENUM类型

编辑:我正在使用@ d1c1pl3建议的DB:raw(),但我仍然想知道使用Eloquent的优雅解决方案。接下来是我的丑陋尝试,使用原始查询并且基于这个答案:https://stackoverflow.com/a/7432219/2465086

public function anyDataReceber() {

// 1 - getting all IDs of clients that have faturamentos or faturamentosLivres

    $clientes = Partner::whereHas('faturamentos', function($q){
            $q->where('status', '<>', 'CANCELADO');
        })
        ->orWhereHas('faturamentosLivres', function ($q) {
            $q->where('status','<>','CANCELADO');
        })
        ->with('faturamentos')
        ->with('faturamentosLivres')
        ->pluck('id')
        ->toArray();

// 2 - Converting to string for use in the query

    $ids = implode(',',$clientes);

// 3 - the ugly query that I want to do using Eloquent. It filters by the status and filters by clients´ ids returned before. It is not appealing either because it uses subselects and a join

    $result = DB::select(DB::raw(
                 'SELECT partners.client, cliente_id, (SUM(t.total_usd) - SUM(t.valor_pago)) AS valores_receber
FROM (SELECT cliente_id, total_usd, valor_pago FROM faturamentos WHERE status <> "CANCELADO" AND cliente_id IN ('.$ids.')
      UNION ALL
      SELECT cliente_id, total_usd, valor_pago FROM faturamentos_livres WHERE status <> "CANCELADO" AND cliente_id IN ('.$ids.')) t
JOIN partners ON partners.id= cliente_id 
GROUP BY cliente_id'
                 ));

// 4 - converting to Collection because the Datatables class expects it

    $result = collect($result);

// 5 - The return is the only part that is easy to read and feels like it is in the right track

    return Datatables::of($result)
        ->editColumn('valores_receber', function ($result) {
            return number_format($result->valores_receber,2,',','.');
        })
        ->addColumn('action', function ($result) {
            $actions = '';
            $actions = '<a href="/admin/financeiro-matriz/contas-receber/'.$result->cliente_id.'" class="btn btn-xs btn-primary"><i class="fa fa-eye"></i> Visualizar</a>';
            return $actions;
        })
        ->make(true);
}

1 个答案:

答案 0 :(得分:0)

如果您知道如何使用mysql,我会使用原始表达式

https://laravel.com/docs/5.4/queries#raw-expressions