仓库销售系统:如何在foreach循环中先校验库存调整状态再控制操作
问题描述
负责仓库商品购销流程,需求如下:
- 若商品处于库存调整待处理(
ajusinv='y')状态,禁止该商品的购销操作 - 需要批量检查某笔销售的所有明细商品,只要存在待调整商品,就不允许执行购销操作,直到调整完成
当前使用Laravel Blade编写的代码存在问题:循环遍历销售明细时,会重复生成审批、拒绝按钮,无法实现先全量校验再执行条件逻辑的需求。
当前错误代码片段:
@foreach ($venta->detalleventas as $detalleventa) @if ($detalleventa->articulo->ajusinv == 'y') <a class="jsgrid-button btn btn-warning"> Ajuste pendiente <i class="fas fa-exclamation-triangle"></i> </a> @break @else <a class="btn btn-success" href="{{ route('cambio.estado.ventas', $venta) }}" title="Aprobar"><i class="fas fa-check"></i> </a> <a class="btn btn-danger text-white" href="{{ route('cambio.rechazado.ventas', $venta) }}" title="Rechazar"><i class="fas fa-ban"></i> </a> @endif @endforeach
解决方案
核心思路是先提前判断该笔销售是否存在待调整商品,再根据判断结果决定显示警告或操作按钮,避免在循环内重复渲染按钮。
步骤1:添加批量判断逻辑
在每笔销售的上下文内,使用Laravel集合的any()方法快速校验是否存在待调整商品:
@php $hasPendingAdjustment = $venta->detalleventas->any(function($detalle) { return $detalle->articulo->ajusinv == 'y'; }); @endphp
步骤2:替换原循环代码
将@can('cambio.estado.ventas')内的循环逻辑替换为如下条件判断:
@can('cambio.estado.ventas') @if($hasPendingAdjustment) <a class="jsgrid-button btn btn-warning"> Ajuste pendiente <i class="fas fa-exclamation-triangle"></i> </a> @else <a class="btn btn-success" href="{{ route('cambio.estado.ventas', $venta) }}" title="Aprobar"><i class="fas fa-check"></i> </a> <a class="btn btn-danger text-white" href="{{ route('cambio.rechazado.ventas', $venta) }}" title="Rechazar"><i class="fas fa-ban"></i> </a> @endif @endcan
完整修改后的表格代码
<table id="order-listing" class="table venta table-hover table-striped mt-0.5 table-bordered shadow-lg dt-responsive"> <thead class="bg-primary text-white"> <tr> <th scope="col" width='10px'>ID</th> <th scope="col" width='50px'>Fecha</th> <th scope="col" width='80px'>Empleado</th> <th scope="col" width='10px'>#</th> <th scope="col" width='350px'>Artículos</th> <th scope="col" width='70px'>Almacenes</th> <th scope="col" width='100px'>Estado</th> <th scope="col" width='165px'>Acciones</th> </tr> </thead> <tbody> @foreach ($ventas as $venta) @php $hasPendingAdjustment = $venta->detalleventas->any(function($detalle) { return $detalle->articulo->ajusinv == 'y'; }); @endphp <tr> <td>{{ $venta->id }}</td> <td> {{ \Carbon\Carbon::parse($venta->created_at)->format('d-m-y') }} </td> <td>{{ ucwords($venta->cliente->nombre) }} {{$venta->cliente->apellido}}</td> <td> @foreach ($venta->detalleventas as $detalleventa) {{$detalleventa->cantidad}} <br> @endforeach </td> <td style="width: 50px;"> @foreach ($venta->detalleventas as $detalleventa) • {{$detalleventa->articulo->nombre}} <br> @endforeach </td> <td> @foreach ($venta->detalleventas as $detalleventa) {{$detalleventa->almacen->nom_alm}} <br> @endforeach </td> <td> <a class="btn btn-warning text-bold" target="_blank">Por aprobar</a> </td> <td style="width: 50px;"> @can('cambio.estado.ventas') @if($hasPendingAdjustment) <a class="jsgrid-button btn btn-warning"> Ajuste pendiente <i class="fas fa-exclamation-triangle"></i> </a> @else <a class="btn btn-success" href="{{ route('cambio.estado.ventas', $venta) }}" title="Aprobar"><i class="fas fa-check"></i> </a> <a class="btn btn-danger text-white" href="{{ route('cambio.rechazado.ventas', $venta) }}" title="Rechazar"><i class="fas fa-ban"></i> </a> @endif @endcan @can('ventas.pdf') <a href="{{ route('ventas.pdf', $venta) }}" class="btn btn-secondary text-bold" title="Imprimir" target="_blank"><i class="fas fa-file-pdf"></i></a> @endcan @can('ventas.show') <a href="{{ route('admin.ventas.show', $venta) }}" class="btn btn-info" title="Ver detalles"><i class="fas fa-eye"></i> </a> @endcan </td> </tr> @endforeach </tbody> </table>
说明
Collection::any()方法可高效判断集合中是否存在符合条件的元素,避免手动循环遍历- 提前完成全量校验,再根据结果渲染对应UI,彻底解决按钮重复问题
- 保留原有的权限控制和其他操作按钮逻辑,不影响原有功能
内容的提问来源于stack exchange,提问作者Karelix Alejandra
相关产品推荐
相关产品推荐

