【问题标题】:Laravel scope for paid invoices with multiplied columns具有相乘列的已付款发票的 Laravel 范围
【发布时间】:2020-04-24 02:31:11
【问题描述】:

这应该很简单,但我无法理解它。我有一张发票表和一张付款表。一张发票有许多付款,总付款金额使用 original_amount * exchange_rate 计算。我需要做的就是确定已付发票的范围。 代码如下:

在 Invoice.php 中

public function payments() {

    return $this->hasMany(Payment::class);
}


public function scopePaid($query) {
    return $query->whereHas('payments', function (Builder $query)) {

        // This is the pseudo code part....
        $query->where('original_amount' * 'exchange_rate', '>=', $invoice->amount_due);

    }

我只是希望它这么简单,但这当然行不通。我总是可以创建一个静态函数,循环检查发票的付款状态并返回一组已付款发票,但这不是范围,我希望找到比这更优雅的东西。有什么想法吗?

谢谢!

【问题讨论】:

    标签: mysql laravel eloquent


    【解决方案1】:

    使用groupByhavingRaw

    $query->groupBy('invoice_id')
          ->havingRaw('SUM(original_amount * exchange_rate) >= invoices.amount_due');
    

    【讨论】:

    • 感谢 TsaiKoga。但显然,这是将每笔付款与发票总额进行比较,这是不可取的。应在每张发票的总付款之间进行比较,因为发票可以分期付款或分期付款。
    • @E.Barney 更新。
    • 再次感谢。我试过:public function scopePaid($query) { return $query->whereHas('payments', function (Builder $query){ return $query->groupBy('invoice_id') ->havingRaw('SUM(original_amount * exchange_rate) >= invoices.amount_due'); }); } 但它没有用。我得到以下信息:
      SQLSTATE[42000]:语法错误或访问冲突:1055 SELECT 列表的表达式 #1 不在 GROUP BY 子句中,并且包含在功能上不依赖于的非聚合列 'lidya.movi​​mientos.id' GROUP BY 子句中的列;这与 sql_mode 不兼容....
    • 我也试过:` public function scopePaid($query) { return $query->groupBy('invoice_id') ->havingRaw('SUM(original_amount * exchange_rate) >= invoices.amount_due '); }` 但也给了我以下错误: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'invoice_id' in 'group statement' (SQL: select id from invoices where invoices.deleted_at is invoice_id 的空组 SUM(original_amount * exchange_rate) >= invoices.amount_due)
    • @E.Barney 这是mysqlonly_full_group_by的问题,试试this,你可以禁用only_full_group_by模式。
    【解决方案2】:

    感谢@TsaiKoga。你真的是大师!

    澄清一下,最终版本是:

    public function scopePaid1($query) {
        return $query->whereHas('payments', function (Builder $query){
            return $query->groupBy('invoice_id')
                ->havingRaw('SUM(original_amount * exchange_rate) >= invoices.amount_due');
        });
    }
    

    按照this 的建议配置数据库很重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 2017-02-13
      相关资源
      最近更新 更多