You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何对pivot中间表字段求和 实现销售订单发货数量校验

前置修正

你现有SalesOrder模型里的shipments关联定义有误,因为一个销售单支持多次发货,应该改为hasMany而不是hasOne:

// SalesOrder.php 修正后
public function shipments()
{
    return $this->hasMany(Shipment::class);
}

实现方案

完全可以通过Eloquent直接统计已发货数量,不需要嵌套foreach遍历,这里提供两种常用实现方式:

方式1:SQL直接统计(数据量大时更推荐,性能更高)

直接通过关联查询统计当前销售单下各商品的总发货量,再和订单商品的下单数量对比:

use Illuminate\Support\Facades\DB;

// 假设$salesOrderId为指定销售单的ID
$salesOrder = SalesOrder::with('products')->findOrFail($salesOrderId);

// 统计当前销售单所有发货单的各商品发货总量
$shippedQtyMap = DB::table('product_shipment')
    ->join('shipments', 'product_shipment.shipment_id', '=', 'shipments.id')
    ->where('shipments.sales_order_id', $salesOrderId)
    ->groupBy('product_id')
    ->pluck(DB::raw('SUM(qty) as total_shipped'), 'product_id');

// 计算各商品可发货最大数量
$availableShipQty = $salesOrder->products->map(function ($product) use ($shippedQtyMap) {
    $orderedQty = $product->pivot->qty;
    $shippedQty = $shippedQtyMap->get($product->id, 0);
    return [
        'product_id' => $product->id,
        'ordered_qty' => $orderedQty,
        'shipped_qty' => $shippedQty,
        'max_ship_qty' => max(0, $orderedQty - $shippedQty)
    ];
})->keyBy('product_id');

方式2:封装为模型访问器(方便全局调用)

可以把逻辑封装到SalesOrder模型的访问器中,后续用的时候直接调用即可:

// 在SalesOrder.php中新增访问器
public function getMaxShipQuantitiesAttribute()
{
    $shippedQtyMap = DB::table('product_shipment')
        ->join('shipments', 'product_shipment.shipment_id', '=', 'shipments.id')
        ->where('shipments.sales_order_id', $this->id)
        ->groupBy('product_id')
        ->pluck(DB::raw('SUM(qty)'), 'product_id');

    return $this->products->mapWithKeys(function ($product) use ($shippedQtyMap) {
        $available = max(0, $product->pivot->qty - $shippedQtyMap->get($product->id, 0));
        return [$product->id => $available];
    });
}

调用方式非常简单:

$salesOrder = SalesOrder::findOrFail($salesOrderId);
// 直接获取商品ID为5的最大可发货数量
echo $salesOrder->max_ship_quantities[5];

额外建议

创建发货单时建议加表单验证,校验本次提交的各商品发货数量不超过对应的最大可发货值,避免超发。

内容的提问来源于stack exchange,提问作者Kevin Jonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 13:06:03