store-manage/app/Http/Controllers/Api/ReimbursementController.php

200 lines
6.4 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Admin\Services\WorkFlowService;
use App\Exceptions\RuntimeException;
use App\Http\Resources\{ReimbursementResource, WorkflowLogResource};
use App\Models\{Keyword, Reimbursement, WorkflowCheck};
use Illuminate\Http\{Request, Response};
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use App\Enums\CheckStatus;
use Throwable;
/**
* 报销管理
*/
class ReimbursementController extends Controller
{
public function index(Request $request)
{
/** @var \App\Models\Employee */
$user = $request->user();
$reimbursements = $user->reimbursements()
->with(['type', 'workflow'])
->filter($request->input())
->sort('created_at', '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, !!$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);
}
}