确认归还

This commit is contained in:
2026-02-12 15:33:23 +08:00
parent 28287e7a7c
commit 7098f30af2
4 changed files with 201 additions and 2 deletions
@@ -138,6 +138,25 @@ class InvRequisitionItemReturnController extends BaseController
} }
} }
/**
* 物品归还确认
*
* @param Request $request
* @return mixed
*/
public function returnItemConfirm(Request $request)
{
try {
// 验证申请数据
$data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm');
// 处理申请逻辑
$result = $this->service->serviceReturnItemConfirm($request, $data, 'returnConfirm');
return $this->success($result, '申请提交成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/** /**
* 物品归还确认 * 物品归还确认
@@ -391,7 +391,7 @@ class InvRequisitionItemReturnService
* @return array|bool * @return array|bool
* @throws BusinessException * @throws BusinessException
*/ */
public function serviceReturnConfirm(Request $request, array $data, string $scene = 'returnConfirm') public function serviceReturnItemConfirm(Request $request, array $data, string $scene = 'returnConfirm')
{ {
try { try {
$attachment = $request->post('attachment'); $attachment = $request->post('attachment');
@@ -543,6 +543,165 @@ class InvRequisitionItemReturnService
} }
} }
/**
* 物品领用归还确认
*
* @param Request $request
* @param array $data
* @param string $scene
* @return array|bool
* @throws BusinessException
*/
public function serviceReturnConfirm(Request $request, array $data, string $scene = 'returnConfirm')
{
try {
$attachment = $request->post('attachment');
unset($data['attachment']);
// 归还确认是业务顶层方法,这里统一使用事务
return Db::transaction(function () use ($request, $data, $scene, $attachment) {
// 1. 当前操作人信息
$userInfo = (new UserService())->getUserInfo($request->user->uid, '');
if (empty($userInfo['user']['id']) || empty($userInfo['user']['name'])) {
throw new BusinessException('无法获取当前用户信息');
}
$handlerId = (int)$userInfo['user']['id'];
$handlerName = (string)$userInfo['user']['name'];
$data['handler_id'] = $handlerId;
$data['handler_name'] = $handlerName;
// 确认状态:1=通过,2=拒绝
$status = isset($data['status']) ? (int)$data['status'] : null;
if (!in_array($status, [1, 2], true)) {
throw new BusinessException('非法的归还处理状态');
}
// 2. 构建查询配置,定位到这条归还记录
$returnService = new InvRequisitionReturnService();
$return = InvRequisitionReturn::where('id', $data['return_id'])->first();
if (!$return) {
throw new BusinessException('未找到对应的领用归还记录');
}
$requisitionId = (int)$return->requisition_id;
$existingStatus = (int)($return->status ?? 0);
if (in_array($existingStatus, [1, 2], true)) {
throw new BusinessException('该归还申请已经被处理过了');
}
$return->status = $status;
$return->save();
// 保存归还审核附件
foreach ($attachment as $attac) {
Db::table('inv_requisition_return_approve_attachment')->insertGetId([
'requisition_id' => $requisitionId,
'return_id' => $data['return_id'],
'file_name' => $attac['original_name'],
'file_path' => $attac['file_path'],
'created_at' => time(),
]);
}
//查询归还明细
$itemReturns = InvRequisitionItemReturn::where('return_id', $data['return_id'])->get();
foreach ($itemReturns as $itemReturn) {
$itemReturn->status = $status;
$itemReturn->handle_remark = $data['handle_remark'];
$itemReturn->save();
// 5. 若是拒绝,直接跳出(不改库存、不改已归还数量)
if ($status === 2) {
// 拒绝:这里你返回 true 或者返回更新后的记录都可以
continue;
}
// 6. 审核通过:继续处理领用明细 & 库存 & 领用单状态
// 注意:requisition_item_id、item_id、return_qty 等字段在本次确认流程中不会被修改,
// 所以可以直接使用 $existingRecord 中的值(都是只读字段)
$requisitionItemId = (int)$itemReturn->requisition_item_id;
$itemId = (int)$itemReturn->item_id;
$returnQty = (int)$itemReturn->return_qty;
if ($requisitionItemId <= 0 || $itemId <= 0 || $returnQty <= 0 || $requisitionId <= 0) {
throw new BusinessException('归还申请记录缺少必要字段,无法处理');
}
// 6.2 处理领用明细
/** @var \app\model\InvRequisitionItem|null $item */
$item = InvRequisitionItem::find($requisitionItemId);
if (!$item) {
throw new BusinessException('未找到对应的领用明细记录');
}
$approvedQty = (int)($item->approved_qty ?? 0);
$returnedQty = (int)($item->returned_qty ?? 0);
if ($approvedQty <= 0) {
throw new BusinessException('该物品尚未审批出库,无法归还');
}
if ($returnedQty + $returnQty > $approvedQty) {
throw new BusinessException('归还数量超过已借数量,无法确认');
}
$item->returned_qty = $returnedQty + $returnQty;
if ($item->returned_qty >= $approvedQty) {
$item->is_finished = 1;
}
$item->updated_at = time();
if ($item->save() === false) {
throw new BusinessException('更新领用明细失败');
}
// 6.3 处理库存(入库)
(new InvItemService())->stockIn($itemId, $returnQty);
}
// 5. 若是拒绝,直接返回(不修改领用申请状态)
if ($status === 2) {
// 拒绝:这里你返回 true 或者返回更新后的记录都可以
return $return;
}
// 6.3 检查整张单是否已全部归还(只看非耗材)
$notFinishedCount = InvRequisitionItem::query()
->where('requisition_id', $requisitionId)
->where('is_consumable_snap', 0)
->where('is_finished', 0)
->count();
if ($notFinishedCount === 0) {
// 全部非耗材都已归还
$affected = InvRequisition::where('id', $requisitionId)->update([
'is_returned' => 1,
'status' => 17,
'updated_at' => time(),
]);
// Eloquent::update 返回的是影响行数,0 表示未更新到任何行
if ($affected === 0) {
throw new BusinessException('更新领用单状态失败,可能记录不存在');
}
}else{
// 非耗材未全部归还
$affected = InvRequisition::where('id', $requisitionId)->update([
'status' => 16,
'updated_at' => time(),
]);
}
// 7. 返回处理结果(保持你原来的 postProcess 习惯)
//return $this->postProcess(ucfirst($scene), $existingRecord);
return $return;
});
} catch (BusinessException $e) {
throw $e;
} catch (\Throwable $e) {
throw new BusinessException("确认归还物品失败:" . $e->getMessage());
}
}
/** /**
* 构建查询配置 * 构建查询配置
* *
@@ -138,6 +138,25 @@ class InvRequisitionItemReturnController extends BaseController
} }
} }
/**
* 物品归还确认
*
* @param Request $request
* @return mixed
*/
public function returnItemConfirm(Request $request)
{
try {
// 验证申请数据
$data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm');
// 处理申请逻辑
$result = $this->service->serviceReturnItemConfirm($request, $data, 'returnConfirm');
return $this->success($result, '申请提交成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/** /**
* 物品归还确认 * 物品归还确认
@@ -152,7 +171,7 @@ class InvRequisitionItemReturnController extends BaseController
$data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm'); $data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm');
// 处理申请逻辑 // 处理申请逻辑
$result = $this->service->serviceReturnConfirm($request, $data, 'returnConfirm'); $result = $this->service->serviceReturnConfirm($request, $data, 'returnConfirm');
return $this->success($result, '申请提交成功'); return $this->success($result, '申请提交成功');
} catch (\Throwable $e) { } catch (\Throwable $e) {
return $this->error($e->getMessage()); return $this->error($e->getMessage());
+2
View File
@@ -528,6 +528,7 @@ Route::group('/admin', function () {
Route::any('/list', [app\common\controller\InvRequisitionItemReturnController::class, 'index']); Route::any('/list', [app\common\controller\InvRequisitionItemReturnController::class, 'index']);
Route::any('/show', [app\common\controller\InvRequisitionItemReturnController::class, 'show']); Route::any('/show', [app\common\controller\InvRequisitionItemReturnController::class, 'show']);
Route::any('/confirm', [app\common\controller\InvRequisitionItemReturnController::class, 'returnConfirm']); Route::any('/confirm', [app\common\controller\InvRequisitionItemReturnController::class, 'returnConfirm']);
Route::any('/confirmItem', [app\common\controller\InvRequisitionItemReturnController::class, 'returnItemConfirm']);
}); });
}); });
}); });
@@ -680,6 +681,7 @@ Route::group('/mobile', function () {
Route::any('/list', [app\mobile\controller\InvRequisitionItemReturnController::class, 'index']); Route::any('/list', [app\mobile\controller\InvRequisitionItemReturnController::class, 'index']);
Route::any('/show', [app\mobile\controller\InvRequisitionItemReturnController::class, 'show']); Route::any('/show', [app\mobile\controller\InvRequisitionItemReturnController::class, 'show']);
Route::any('/confirm', [app\mobile\controller\InvRequisitionItemReturnController::class, 'returnConfirm']); Route::any('/confirm', [app\mobile\controller\InvRequisitionItemReturnController::class, 'returnConfirm']);
Route::any('/confirmItem', [app\mobile\controller\InvRequisitionItemReturnController::class, 'returnItemConfirm']);
}); });
}); });
}); });