物品扫码领用与库存
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\model\InvItem;
|
||||
use app\common\model\InvStockLog;
|
||||
use app\common\validate\InvRequisitionValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InvRequisition;
|
||||
@@ -313,4 +314,268 @@ class InvRequisitionService
|
||||
{
|
||||
return 'RQ' . date('Ymd') . strtoupper(substr(uniqid(), -6));
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码领取物品
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function qrClaim(Request $request, array $data): array
|
||||
{
|
||||
return Db::transaction(function () use ($request, $data) {
|
||||
$itemId = (int)($data['item_id'] ?? 0);
|
||||
$qty = (int)($data['qty'] ?? 1);
|
||||
|
||||
if ($itemId <= 0) {
|
||||
throw new BusinessException('物品ID无效');
|
||||
}
|
||||
if ($qty <= 0) {
|
||||
throw new BusinessException('领取数量必须大于0');
|
||||
}
|
||||
|
||||
// 获取物品信息
|
||||
$item = InvItem::find($itemId);
|
||||
if (!$item) {
|
||||
throw new BusinessException('物品不存在');
|
||||
}
|
||||
|
||||
// 检查是否允许扫码领取
|
||||
if (!$item->allow_qr_claim) {
|
||||
throw new BusinessException('该物品不允许扫码领取');
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
$user = (new UserService())->getUserInfo($request->user->uid, '');
|
||||
$applicantId = (int)$user['user']['id'];
|
||||
$applicantName = (string)$user['user']['name'];
|
||||
|
||||
// 检查库存
|
||||
if ($item->stock_qty < $qty) {
|
||||
throw new BusinessException('库存不足,当前库存: ' . $item->stock_qty);
|
||||
}
|
||||
|
||||
// 创建领用申请记录(直接完成)
|
||||
$requisition = InvRequisition::create([
|
||||
'order_no' => $this->generateOrderNo(),
|
||||
'applicant_company_id' => $user['user']['company_id'] ?? 0,
|
||||
'dept_id' => $user['user']['dept_id'] ?? 0,
|
||||
'applicant_id' => $applicantId,
|
||||
'applicant_name' => $applicantName,
|
||||
'leader_id' => $user['user']['report_to'] ?? 0,
|
||||
'manager_id' => $item->manage_user_id,
|
||||
'borrow_reason' => '扫码领取',
|
||||
'use_start_date' => date('Y-m-d', time()),
|
||||
'use_end_date' => date('Y-m-d', time()),
|
||||
'status' => 19, // 已审批(无需归还)
|
||||
'claim_type' => InvRequisition::CLAIM_TYPE_QR,
|
||||
'qr_claim_time' => time(),
|
||||
'remark' => $data['remark'] ?? '扫码领取',
|
||||
]);
|
||||
|
||||
// 创建领用明细
|
||||
InvRequisitionItem::create([
|
||||
'requisition_id' => $requisition->id,
|
||||
'item_id' => $itemId,
|
||||
'item_name_snap' => $item->item_name,
|
||||
'spec_model_snap' => $item->spec_model,
|
||||
'unit_snap' => $item->unit,
|
||||
'is_consumable_snap' => $item->is_consumable,
|
||||
'request_qty' => $qty,
|
||||
'approved_qty' => $qty,
|
||||
'remark' => '扫码领取',
|
||||
]);
|
||||
|
||||
// 扣减库存
|
||||
(new InvItemService())->stockOut($itemId, $qty, false, [
|
||||
'biz_type' => InvStockLog::BIZ_TYPE_QR_CLAIM,
|
||||
'biz_no' => $requisition->order_no,
|
||||
'operator_id' => $applicantId,
|
||||
'operator_name' => $applicantName,
|
||||
'remark' => '扫码领取',
|
||||
]);
|
||||
|
||||
return $requisition->toArray();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员代领
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function proxyClaim(Request $request, array $data): array
|
||||
{
|
||||
return Db::transaction(function () use ($request, $data) {
|
||||
$itemId = (int)($data['item_id'] ?? 0);
|
||||
$qty = (int)($data['qty'] ?? 1);
|
||||
$targetUserId = (int)($data['target_user_id'] ?? 0);
|
||||
|
||||
if ($itemId <= 0) {
|
||||
throw new BusinessException('物品ID无效');
|
||||
}
|
||||
if ($qty <= 0) {
|
||||
throw new BusinessException('领取数量必须大于0');
|
||||
}
|
||||
if ($targetUserId <= 0) {
|
||||
throw new BusinessException('请选择代领用户');
|
||||
}
|
||||
|
||||
// 获取物品信息
|
||||
$item = InvItem::find($itemId);
|
||||
if (!$item) {
|
||||
throw new BusinessException('物品不存在');
|
||||
}
|
||||
|
||||
// 获取操作人(管理员)信息
|
||||
$proxyUser = (new UserService())->getUserInfo($request->user->uid, '');
|
||||
$proxyUserId = (int)$proxyUser['user']['id'];
|
||||
$proxyUserName = (string)$proxyUser['user']['name'];
|
||||
|
||||
// 验证操作人是否是物品管理员
|
||||
if ($item->manage_user_id != $proxyUserId) {
|
||||
throw new BusinessException('您不是该物品的管理员,无权代领');
|
||||
}
|
||||
|
||||
// 获取目标用户信息
|
||||
$targetUser = (new UserService())->getUserInfo($targetUserId, '');
|
||||
if (!$targetUser['user']) {
|
||||
throw new BusinessException('目标用户不存在');
|
||||
}
|
||||
|
||||
// 检查库存
|
||||
if ($item->stock_qty < $qty) {
|
||||
throw new BusinessException('库存不足,当前库存: ' . $item->stock_qty);
|
||||
}
|
||||
|
||||
// 创建领用申请记录(直接完成)
|
||||
$requisition = InvRequisition::create([
|
||||
'order_no' => $this->generateOrderNo(),
|
||||
'applicant_company_id' => $targetUser['user']['company_id'] ?? 0,
|
||||
'dept_id' => $targetUser['user']['dept_id'] ?? 0,
|
||||
'applicant_id' => $targetUserId,
|
||||
'applicant_name' => $targetUser['user']['name'],
|
||||
'leader_id' => $targetUser['user']['report_to'] ?? 0,
|
||||
'manager_id' => $item->manage_user_id,
|
||||
'borrow_reason' => $data['borrow_reason'] ?? '管理员代领',
|
||||
'use_start_date' => date('Y-m-d', time()),
|
||||
'use_end_date' => date('Y-m-d', time()),
|
||||
'status' => 19, // 已审批(无需归还)
|
||||
'claim_type' => InvRequisition::CLAIM_TYPE_PROXY,
|
||||
'proxy_claim_user_id' => $proxyUserId,
|
||||
'proxy_claim_user_name' => $proxyUserName,
|
||||
'remark' => $data['remark'] ?? '管理员代领',
|
||||
]);
|
||||
|
||||
// 创建领用明细
|
||||
InvRequisitionItem::create([
|
||||
'requisition_id' => $requisition->id,
|
||||
'item_id' => $itemId,
|
||||
'item_name_snap' => $item->item_name,
|
||||
'spec_model_snap' => $item->spec_model,
|
||||
'unit_snap' => $item->unit,
|
||||
'is_consumable_snap' => $item->is_consumable,
|
||||
'request_qty' => $qty,
|
||||
'approved_qty' => $qty,
|
||||
'remark' => $data['remark'] ?? '管理员代领',
|
||||
]);
|
||||
|
||||
// 扣减库存
|
||||
(new InvItemService())->stockOut($itemId, $qty, false, [
|
||||
'biz_type' => InvStockLog::BIZ_TYPE_PROXY_CLAIM,
|
||||
'biz_no' => $requisition->order_no,
|
||||
'operator_id' => $proxyUserId,
|
||||
'operator_name' => $proxyUserName,
|
||||
'remark' => '管理员代领',
|
||||
]);
|
||||
|
||||
return $requisition->toArray();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询扫码/代领记录列表
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function qrClaimsList(Request $request): array
|
||||
{
|
||||
$query = InvRequisition::query()->with(['items']);
|
||||
|
||||
// 只查询扫码领取和代领记录
|
||||
$query->whereIn('claim_type', [
|
||||
InvRequisition::CLAIM_TYPE_QR,
|
||||
InvRequisition::CLAIM_TYPE_PROXY
|
||||
]);
|
||||
|
||||
// 按申请人筛选(移动端"我的记录"功能)
|
||||
if ($request->get('applicant_id') === 'self') {
|
||||
$query->where('applicant_id', $request->user->uid);
|
||||
} elseif (!empty($request->get('applicant_id'))) {
|
||||
$query->where('applicant_id', $request->get('applicant_id'));
|
||||
}
|
||||
|
||||
// 按领取方式筛选
|
||||
if (!empty($request->get('claim_type'))) {
|
||||
$query->where('claim_type', $request->get('claim_type'));
|
||||
}
|
||||
|
||||
// 按代领操作人筛选
|
||||
if (!empty($request->get('proxy_user_id'))) {
|
||||
$query->where('proxy_claim_user_id', $request->get('proxy_user_id'));
|
||||
}
|
||||
|
||||
// 时间范围筛选
|
||||
if (!empty($request->get('start_time'))) {
|
||||
$query->where('qr_claim_time', '>=', strtotime($request->get('start_time')));
|
||||
}
|
||||
if (!empty($request->get('end_time'))) {
|
||||
$query->where('qr_claim_time', '<=', strtotime($request->get('end_time')));
|
||||
}
|
||||
|
||||
// 排序
|
||||
$query->orderBy('id', 'desc');
|
||||
|
||||
// 分页
|
||||
$perPage = $request->get('size', 20);
|
||||
$page = $request->get('current', 1);
|
||||
|
||||
$result = $query->paginate($perPage, ['*'], 'page', $page);
|
||||
|
||||
return [
|
||||
'records' => $result->getCollection()->map(function ($req) {
|
||||
return [
|
||||
'id' => $req->id,
|
||||
'order_no' => $req->order_no,
|
||||
'applicant_id' => $req->applicant_id,
|
||||
'applicant_name' => $req->applicant_name,
|
||||
'claim_type' => $req->claim_type,
|
||||
'claim_type_text' => InvRequisition::getClaimTypeText($req->claim_type),
|
||||
'qr_claim_time' => $req->qr_claim_time ? date('Y-m-d H:i:s', $req->qr_claim_time) : null,
|
||||
'proxy_claim_user_id' => $req->proxy_claim_user_id,
|
||||
'proxy_claim_user_name' => $req->proxy_claim_user_name,
|
||||
'status' => $req->status,
|
||||
'borrow_reason' => $req->borrow_reason,
|
||||
'remark' => $req->remark,
|
||||
'created_at' => $req->created_at ? $req->created_at->format('Y-m-d H:i:s') : null,
|
||||
'items' => $req->items->map(function ($item) {
|
||||
return [
|
||||
'item_id' => $item->item_id,
|
||||
'item_name_snap' => $item->item_name_snap,
|
||||
'approved_qty' => $item->approved_qty,
|
||||
];
|
||||
})->toArray(),
|
||||
];
|
||||
})->toArray(),
|
||||
'total' => $result->total(),
|
||||
'current' => $result->currentPage(),
|
||||
'size' => $result->perPage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user