stockService = $stockService; } /** * 生成采购单号 */ public function generatePoNo() { $prefix = 'PO'; $date = date('Ymd'); $last = PurchaseOrder::where('po_no', 'like', $prefix . $date . '%') ->orderBy('po_no', 'desc') ->first(); if ($last) { $num = intval(substr($last->po_no, -4)) + 1; } else { $num = 1; } return $prefix . $date . str_pad($num, 4, '0', STR_PAD_LEFT); } /** * 生成收货单号 */ public function generateReceivingNo() { $prefix = 'RO'; $date = date('Ymd'); $last = ReceivingOrder::where('receiving_no', 'like', $prefix . $date . '%') ->orderBy('receiving_no', 'desc') ->first(); if ($last) { $num = intval(substr($last->receiving_no, -4)) + 1; } else { $num = 1; } return $prefix . $date . str_pad($num, 4, '0', STR_PAD_LEFT); } /** * 审核采购单 */ public function approve(PurchaseOrder $order) { if ($order->status !== 'under_review') { throw new \Exception('采购单状态错误,无法审核'); } DB::transaction(function () use ($order) { $order->status = 'approved'; $order->save(); // 自动生成收货单 $receivingNo = $this->generateReceivingNo(); $totalQty = $order->items->sum('quantity'); $receivingOrder = ReceivingOrder::create([ 'receiving_no' => $receivingNo, 'po_id' => $order->id, 'warehouse_id' => $order->warehouse_id, 'total_quantity' => $totalQty, 'received_quantity' => 0, 'status' => 'pending', 'receiver' => null, 'is_cloud_warehouse' => $order->cloud_system ? true : false, ]); foreach ($order->items as $item) { ReceivingOrderItem::create([ 'receiving_order_id' => $receivingOrder->id, 'sku_code' => $item->sku_code, 'sku_name' => $item->sku_name, 'order_quantity' => $item->quantity, 'received_quantity' => 0, ]); } }); return $order; } /** * 驳回采购单 */ public function reject(PurchaseOrder $order, $comment) { if ($order->status !== 'under_review') { throw new \Exception('采购单状态错误,无法驳回'); } $order->status = 'rejected'; $order->audit_comment = $comment; $order->save(); return $order; } /** * 执行收货 */ public function receive(ReceivingOrder $receivingOrder, array $items, $receiver) { if ($receivingOrder->status === 'completed') { throw new \Exception('收货单已完成,无法再次收货'); } DB::transaction(function () use ($receivingOrder, $items, $receiver) { $totalReceived = 0; $po = $receivingOrder->purchaseOrder; foreach ($receivingOrder->items as $orderItem) { $found = collect($items)->firstWhere('sku_code', $orderItem->sku_code); if ($found) { $qty = min($found['received_quantity'], $orderItem->order_quantity - $orderItem->received_quantity); if ($qty > 0) { $orderItem->received_quantity += $qty; $orderItem->save(); // 入库到库存 $this->stockService->inbound( $orderItem->sku_code, $receivingOrder->warehouse_id, $qty, $po->po_no, '采购入库,采购单号:' . $po->po_no ); $totalReceived += $qty; } } } $receivingOrder->received_quantity += $totalReceived; $receivingOrder->receiver = $receiver; if ($receivingOrder->received_quantity >= $receivingOrder->total_quantity) { $receivingOrder->status = 'completed'; $allCompleted = $po->receivingOrders()->where('status', '!=', 'completed')->count() == 0; if ($allCompleted && $po->status !== 'completed') { $po->status = 'completed'; $po->save(); } } else { $receivingOrder->status = 'partial'; } $receivingOrder->save(); }); return $receivingOrder->fresh(); } /** * 推送云仓(模拟) */ public function pushToCloud(PurchaseOrder $order) { if ($order->pushed_to_cloud) { throw new \Exception('采购单已推送过云仓'); } // 模拟推送逻辑,实际应调用对应云仓API try { $response = ['success' => true, 'message' => '推送成功', 'cloud_po_no' => 'CLOUD_' . $order->po_no]; $order->pushed_to_cloud = true; $order->pushed_at = now(); $order->cloud_response = json_encode($response); $order->save(); return $response; } catch (\Exception $e) { throw new \Exception('推送云仓失败:' . $e->getMessage()); } } }