user(); $reimbursements = $user->reimbursements() ->with(['type', 'workflow']) ->filter($request->input()) ->orderByDesc(WorkflowCheck::checkStatusSortBuilder(new Reimbursement())) ->orderBy('id', 'desc') ->paginate($request->input('per_page', 20)); return ReimbursementResource::collection($reimbursements); } public function store(Request $request, WorkFlowService $workFlowService): ReimbursementResource { $validated = $request->validate( rules: [ 'reimbursement_type_id' => ['bail', 'required', Rule::exists(Keyword::class, 'key')], 'expense' => ['bail', 'required', 'min:0', 'max:99999999', 'decimal:0,2'], 'reason' => ['bail', 'required', 'max:255'], 'photos' => ['bail', 'required', 'array'], ], attributes: [ 'reimbursement_type_id' => '报销分类', 'expense' => '报销金额', 'reason' => '报销原因', 'photos' => '报销凭证', ], ); /** @var \App\Models\Employee */ $user = $request->user(); try { DB::beginTransaction(); $validated['store_id'] = $user->store_id; /** @var \App\Models\Reimbursement */ $reimbursement = $user->reimbursements()->create($validated); $workFlowService->apply($reimbursement->workflow, $user); DB::commit(); } catch (Throwable $th) { DB::rollBack(); throw tap($th, fn ($th) => report($th)); } return ReimbursementResource::make( $reimbursement->load(['type', 'workflow']), ); } public function show($id, Request $request): ReimbursementResource { $reimbursement = Reimbursement::with(['type', 'workflow', 'employee', 'store'])->findOrFail($id); return ReimbursementResource::make($reimbursement); } public function update($id, Request $request, WorkFlowService $workFlowService): ReimbursementResource { $validated = $request->validate( rules: [ 'reimbursement_type_id' => ['bail', 'required', Rule::exists(Keyword::class, 'key')], 'expense' => ['bail', 'required', 'numeric', 'min:0'], 'reason' => ['bail', 'required', 'max:255'], 'photos' => ['bail', 'required', 'array'], ], attributes: [ 'reimbursement_type_id' => '报销分类', 'expense' => '报销金额', 'reason' => '报销原因', 'photos' => '报销凭证', ], ); /** @var \App\Models\Employee */ $user = $request->user(); /** @var \App\Models\Reimbursement */ $reimbursement = $user->reimbursements()->find($id); if (is_null($reimbursement)) { throw new RuntimeException('报销记录未找到'); } if (! $reimbursement->canUpdate()) { throw new RuntimeException('['.$reimbursement->workflow->check_status->text().']报销记录不可修改'); } try { DB::beginTransaction(); $reimbursement->update($validated); $workFlowService->apply($reimbursement->workflow, $user); DB::commit(); } catch (Throwable $th) { DB::rollBack(); throw tap($th, fn ($th) => report($th)); } return ReimbursementResource::make( $reimbursement->load(['type', 'workflow']), ); } public function destroy($id, Request $request) { /** @var \App\Models\Employee */ $user = $request->user(); /** @var \App\Models\Reimbursement */ $reimbursement = $user->reimbursements()->find($id); if (is_null($reimbursement)) { throw new RuntimeException('报销记录未找到'); } if (! $reimbursement->canDelete()) { throw new RuntimeException('['.$reimbursement->workflow->check_status->text().']报销记录不可删除'); } $reimbursement->delete(); return response()->noContent(); } public function checkList(Request $request) { $user = $request->user(); $query = Reimbursement::with(['workflow', 'type', 'store']) ->whereHas('workflow', fn ($q) => $q->where('check_status', CheckStatus::Processing)) ->whereHas('workflow.logs', fn ($q) => $q->own($user))->orderBy('created_at', 'desc'); $list = $query->paginate($request->input('per_page')); return ReimbursementResource::collection($list); } public function check($id, Request $request, WorkFlowService $workFlowService) { $request->validate([ 'status' => ['required'], 'remarks' => [Rule::requiredIf(fn () => ! $request->input('status'))], ], [ 'remarks.required_if' => '未通过原因必填', ]); $info = Reimbursement::findOrFail($id); $user = $request->user(); try { DB::beginTransaction(); $log = $info->workflow->logs()->where('check_status', CheckStatus::Processing)->first(); if (! $log) { throw new RuntimeException('审核已经完成'); } if (! $workFlowService->check($user, $log, (bool) $request->input('status'), ['remarks' => $request->input('remarks')])) { throw new RuntimeException($workFlowService->getError()); } DB::commit(); return response('', Response::HTTP_OK); } catch (\Exception $e) { DB::rollBack(); throw new RuntimeException($e->getMessage()); } } public function logs($id) { $info = Reimbursement::findOrFail($id); $logs = $info->workflow->logs()->sort()->get(); return WorkflowLogResource::collection($logs); } }