369 lines
13 KiB
PHP
369 lines
13 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\PurchaseOrder;
|
|
use App\Models\PurchaseOrderItem;
|
|
use App\Models\ReceivingOrder;
|
|
use App\Models\ReceivingOrderItem;
|
|
use App\Services\PurchaseService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
|
class PurchaseOrderController extends Controller
|
|
{
|
|
protected $purchaseService;
|
|
|
|
public function __construct(PurchaseService $purchaseService)
|
|
{
|
|
$this->purchaseService = $purchaseService;
|
|
}
|
|
|
|
/**
|
|
* 采购单列表
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
$query = PurchaseOrder::with(['supplier', 'warehouse', 'items']);
|
|
|
|
// 筛选条件
|
|
if ($request->has('po_no')) {
|
|
$query->where('po_no', 'like', '%' . $request->po_no . '%');
|
|
}
|
|
if ($request->has('supplier_id')) {
|
|
$query->where('supplier_id', $request->supplier_id);
|
|
}
|
|
if ($request->has('warehouse_id')) {
|
|
$query->where('warehouse_id', $request->warehouse_id);
|
|
}
|
|
if ($request->has('status')) {
|
|
$query->where('status', $request->status);
|
|
}
|
|
if ($request->has('date_from')) {
|
|
$query->whereDate('created_at', '>=', $request->date_from);
|
|
}
|
|
if ($request->has('date_to')) {
|
|
$query->whereDate('created_at', '<=', $request->date_to);
|
|
}
|
|
|
|
$perPage = $request->get('per_page', 15);
|
|
$orders = $query->orderBy('id', 'desc')->paginate($perPage);
|
|
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => $orders,
|
|
'message' => 'success'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 创建采购单
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'warehouse_id' => 'required|exists:warehouses,id',
|
|
'supplier_id' => 'required|exists:suppliers,id',
|
|
'expected_arrival' => 'nullable|date',
|
|
'shipping_method' => 'nullable|string|max:50',
|
|
'freight' => 'nullable|numeric|min:0',
|
|
'category' => 'nullable|string|max:100',
|
|
'remark' => 'nullable|string',
|
|
'items' => 'required|array|min:1',
|
|
'items.*.sku_code' => 'required|string',
|
|
'items.*.sku_name' => 'required|string',
|
|
'items.*.quantity' => 'required|integer|min:1',
|
|
'items.*.price' => 'required|numeric|min:0',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'code' => 422,
|
|
'message' => '验证失败',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
|
|
// 生成采购单号
|
|
$poNo = 'PO' . date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
|
|
|
|
$purchaseOrder = PurchaseOrder::create([
|
|
'po_no' => $poNo,
|
|
'warehouse_id' => $request->warehouse_id,
|
|
'supplier_id' => $request->supplier_id,
|
|
'expected_arrival' => $request->expected_arrival,
|
|
'shipping_method' => $request->shipping_method,
|
|
'freight' => $request->freight ?? 0,
|
|
'category' => $request->category,
|
|
'remark' => $request->remark,
|
|
'status' => 'draft',
|
|
]);
|
|
|
|
foreach ($request->items as $item) {
|
|
PurchaseOrderItem::create([
|
|
'purchase_order_id' => $purchaseOrder->id,
|
|
'sku_code' => $item['sku_code'],
|
|
'sku_name' => $item['sku_name'],
|
|
'quantity' => $item['quantity'],
|
|
'received_quantity' => 0,
|
|
'price' => $item['price'],
|
|
]);
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return response()->json([
|
|
'code' => 201,
|
|
'data' => $purchaseOrder->load('items'),
|
|
'message' => '采购单创建成功'
|
|
], 201);
|
|
|
|
} catch (\Exception $e) {
|
|
DB::rollBack();
|
|
return response()->json([
|
|
'code' => 500,
|
|
'message' => '创建失败:' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 采购单详情
|
|
*/
|
|
public function show($id)
|
|
{
|
|
$order = PurchaseOrder::with(['supplier', 'warehouse', 'items'])->find($id);
|
|
if (!$order) {
|
|
return response()->json([
|
|
'code' => 404,
|
|
'message' => '采购单不存在'
|
|
], 404);
|
|
}
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => $order,
|
|
'message' => 'success'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 更新采购单(仅草稿状态可更新)
|
|
*/
|
|
public function update(Request $request, $id)
|
|
{
|
|
$purchaseOrder = PurchaseOrder::find($id);
|
|
if (!$purchaseOrder) {
|
|
return response()->json(['code' => 404, 'message' => '采购单不存在'], 404);
|
|
}
|
|
|
|
if ($purchaseOrder->status !== 'draft') {
|
|
return response()->json(['code' => 403, 'message' => '仅草稿状态可修改'], 403);
|
|
}
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'warehouse_id' => 'sometimes|exists:warehouses,id',
|
|
'supplier_id' => 'sometimes|exists:suppliers,id',
|
|
'expected_arrival' => 'nullable|date',
|
|
'shipping_method' => 'nullable|string|max:50',
|
|
'freight' => 'nullable|numeric|min:0',
|
|
'category' => 'nullable|string|max:100',
|
|
'remark' => 'nullable|string',
|
|
'items' => 'sometimes|array|min:1',
|
|
'items.*.sku_code' => 'required_with:items|string',
|
|
'items.*.sku_name' => 'required_with:items|string',
|
|
'items.*.quantity' => 'required_with:items|integer|min:1',
|
|
'items.*.price' => 'required_with:items|numeric|min:0',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json(['code' => 422, 'message' => '验证失败', 'errors' => $validator->errors()], 422);
|
|
}
|
|
|
|
DB::beginTransaction();
|
|
try {
|
|
$purchaseOrder->update($request->only([
|
|
'warehouse_id', 'supplier_id', 'expected_arrival',
|
|
'shipping_method', 'freight', 'category', 'remark'
|
|
]));
|
|
|
|
if ($request->has('items')) {
|
|
$purchaseOrder->items()->delete();
|
|
foreach ($request->items as $item) {
|
|
$purchaseOrder->items()->create([
|
|
'sku_code' => $item['sku_code'],
|
|
'sku_name' => $item['sku_name'],
|
|
'quantity' => $item['quantity'],
|
|
'received_quantity' => 0,
|
|
'price' => $item['price'],
|
|
]);
|
|
}
|
|
}
|
|
|
|
DB::commit();
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => $purchaseOrder->load('items'),
|
|
'message' => '更新成功'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
DB::rollBack();
|
|
return response()->json(['code' => 500, 'message' => '更新失败:' . $e->getMessage()], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 提交审核
|
|
*/
|
|
public function submitReview($id)
|
|
{
|
|
$purchaseOrder = PurchaseOrder::find($id);
|
|
if (!$purchaseOrder) {
|
|
return response()->json(['code' => 404, 'message' => '采购单不存在'], 404);
|
|
}
|
|
if ($purchaseOrder->status !== 'draft') {
|
|
return response()->json(['code' => 403, 'message' => '仅草稿状态可提交审核'], 403);
|
|
}
|
|
|
|
$purchaseOrder->status = 'under_review';
|
|
$purchaseOrder->save();
|
|
|
|
return response()->json(['code' => 200, 'message' => '提交审核成功']);
|
|
}
|
|
|
|
/**
|
|
* 审核通过
|
|
*/
|
|
public function approve($id)
|
|
{
|
|
\Log::info('approve method entered', ['id' => $id, 'time' => now()]);
|
|
|
|
$purchaseOrder = PurchaseOrder::with('items')->find($id);
|
|
if (!$purchaseOrder) {
|
|
return response()->json(['code' => 404, 'message' => '采购单不存在'], 404);
|
|
}
|
|
if ($purchaseOrder->status !== 'under_review') {
|
|
return response()->json(['code' => 403, 'message' => '仅待审核状态可审核通过'], 403);
|
|
}
|
|
|
|
DB::beginTransaction();
|
|
try {
|
|
$purchaseOrder->status = 'approved';
|
|
// 临时注释掉以下两行,避免字段缺失错误
|
|
// $purchaseOrder->approved_at = now();
|
|
// $purchaseOrder->approved_by = auth()->id() ?? 1;
|
|
$purchaseOrder->save();
|
|
|
|
// 计算总数量
|
|
$totalQuantity = $purchaseOrder->items->sum('quantity');
|
|
|
|
// 自动生成收货单
|
|
$receivingOrder = ReceivingOrder::create([
|
|
'receiving_no' => 'RO' . date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT),
|
|
'po_id' => $purchaseOrder->id,
|
|
'warehouse_id' => $purchaseOrder->warehouse_id,
|
|
'total_quantity' => $totalQuantity,
|
|
'received_quantity' => 0,
|
|
'status' => 'pending',
|
|
'is_cloud_warehouse' => false, // 默认为false
|
|
// 其他可选字段:'receiver', 'remark' 暂不设置
|
|
]);
|
|
|
|
foreach ($purchaseOrder->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,
|
|
]);
|
|
}
|
|
|
|
DB::commit();
|
|
return response()->json(['code' => 200, 'message' => '审核通过,已生成收货单']);
|
|
} catch (\Exception $e) {
|
|
DB::rollBack();
|
|
\Log::error('Approve failed', [
|
|
'error' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
return response()->json(['code' => 500, 'message' => '审核失败:' . $e->getMessage()], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 驳回审核
|
|
*/
|
|
public function reject(Request $request, $id)
|
|
{
|
|
$purchaseOrder = PurchaseOrder::find($id);
|
|
if (!$purchaseOrder) {
|
|
return response()->json(['code' => 404, 'message' => '采购单不存在'], 404);
|
|
}
|
|
if ($purchaseOrder->status !== 'under_review') {
|
|
return response()->json(['code' => 403, 'message' => '仅待审核状态可驳回'], 403);
|
|
}
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'reason' => 'required|string'
|
|
]);
|
|
if ($validator->fails()) {
|
|
return response()->json(['code' => 422, 'message' => '请填写驳回原因', 'errors' => $validator->errors()], 422);
|
|
}
|
|
|
|
$purchaseOrder->status = 'rejected';
|
|
$purchaseOrder->reject_reason = $request->reason;
|
|
$purchaseOrder->save();
|
|
|
|
return response()->json(['code' => 200, 'message' => '已驳回']);
|
|
}
|
|
|
|
/**
|
|
* 推送云仓(模拟)
|
|
*/
|
|
public function pushCloud($id)
|
|
{
|
|
$purchaseOrder = PurchaseOrder::find($id);
|
|
if (!$purchaseOrder) {
|
|
return response()->json(['code' => 404, 'message' => '采购单不存在'], 404);
|
|
}
|
|
if ($purchaseOrder->status !== 'approved') {
|
|
return response()->json(['code' => 403, 'message' => '仅审核通过的采购单可推送云仓'], 403);
|
|
}
|
|
|
|
$result = $this->purchaseService->pushToCloud($purchaseOrder);
|
|
|
|
if ($result['success']) {
|
|
$purchaseOrder->cloud_push_status = 'pushed';
|
|
$purchaseOrder->cloud_push_time = now();
|
|
$purchaseOrder->save();
|
|
return response()->json(['code' => 200, 'message' => '推送成功', 'data' => $result]);
|
|
} else {
|
|
return response()->json(['code' => 500, 'message' => '推送失败', 'error' => $result['error']], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 删除采购单(仅草稿)
|
|
*/
|
|
public function destroy($id)
|
|
{
|
|
$purchaseOrder = PurchaseOrder::find($id);
|
|
if (!$purchaseOrder) {
|
|
return response()->json(['code' => 404, 'message' => '采购单不存在'], 404);
|
|
}
|
|
if ($purchaseOrder->status !== 'draft') {
|
|
return response()->json(['code' => 403, 'message' => '仅草稿状态可删除'], 403);
|
|
}
|
|
|
|
DB::transaction(function () use ($purchaseOrder) {
|
|
$purchaseOrder->items()->delete();
|
|
$purchaseOrder->delete();
|
|
});
|
|
|
|
return response()->json(['code' => 200, 'message' => '删除成功']);
|
|
}
|
|
} |