<?php declare(strict_types=1); namespace App\Http\Controllers\Api\V1; use App\Attributes\OpenApiResponse; use App\Domain\Payment\PaymentService; use App\Domain\Payment\Requests\ChangePaymentStatusRequest; use App\Domain\Payment\Requests\CreatePaymentRequest; use App\Http\Controllers\Api\ApiController; use App\Http\Resources\PaymentsStatusResource; use App\Imports\PaymentImport; use App\Models\Payment; use App\Models\PaymentDistribution; use App\Requests\SimilarPaymentRequest; use App\Responses\MessageResponse; use App\Responses\ResourceResponse; use Illuminate\Http\Request; use Knuckles\Scribe\Attributes\Group; use Maatwebsite\Excel\Facades\Excel; final class PaymentController extends ApiController { /** * @var PaymentService|mixed|object */ private mixed $paymentService; public function __construct() { $this->paymentService = app()->make(PaymentService::class); } /** * Список платежей * @queryParam name string Поисковый запрос для фильтрации. Пример: "Laravel" * @queryParam payment_date_from дата платежа * @queryParam payment_date_to дата платежа * @queryParam created_at_from дата создания * @queryParam created_at_to дата создания * @queryParam status * @queryParam contragent_id * @queryParam payment_type * @queryParam id * @queryParam name * @queryParam sorting [status=>ASC|DESC, user=>ASC|DESC, payment_date=>ASC|DESC, amount=>ASC|DESC, contragent=>ASC|DESC, article=>ASC|DESC, organization=>ASC|DESC] * @queryParam project_id * @queryParam article_id * @queryParam creator_id * @queryParam account_id * @queryParam organization_id */ #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function index(int $modelID, Request $request) { list($data, $nextDate, $statistics) = $this->paymentService ->setUserID(auth()->id()) ->getAll($modelID, $request); $results = []; /** @var Payment $item */ foreach ($data as $item) { $item->forceFill([ 'comment' => $item->getLastCommentAttribute(), 'prev_status' => $item->getLastStatusAttribute(), ]); if (empty($results[$item->payment_date])) { $results[$item->payment_date] = [ 'date' => $item->payment_date, 'payments' => [], 'sum' => 0 ]; } $results[$item->payment_date]['payments'][] = $item; $results[$item->payment_date]['sum'] += $item->amount; } $return = []; foreach ($results as $date => $data) { $return[] = $data; } return new ResourceResponse( data: [ 'statistics' => $statistics, 'payments' => $return, 'next_date' => $nextDate ], status: 200 ); } /** * Платеж по ID * */ #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function show(int $modelID, int $id): ResourceResponse { return new ResourceResponse( data: $this->paymentService->getByID($id)->fillWithDistribution()->fillWithLogs(), status: 200 ); } /** * Похожие платежи * */ #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function similarPaymentsByPaymentId(int $modelID, int $id): ResourceResponse { return new ResourceResponse( data: $this->paymentService->getSimilarPaymentsByPaymentId($id), status: 200 ); } #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function similarPaymentsByParams(int $modelID, SimilarPaymentRequest $request): ResourceResponse { $data = $request->validated(); return new ResourceResponse( data: $this->paymentService->getSimilarPayments($modelID, (int)$data['counterparty_id'], $data['amount'], $data['payment_date']), status: 200 ); } /** * Создать новый платеж */ #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function store(int $modelID, CreatePaymentRequest $request): ResourceResponse { return new ResourceResponse( data: $this->paymentService->setUserID(auth()->id())->createNew($modelID, $request), status: 200 ); } /** * Сменить статус платежа */ #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function changeStatus(int $modelID, int $id, ChangePaymentStatusRequest $request): MessageResponse { $this->paymentService->setUserID(auth()->id())->changeStatus($id, $request); return new MessageResponse( message: 'Статус обновлен', status: 200 ); } /** * Сменить статус платежа по статусной модели * @queryParam move_to => [next, previous, rollback] * @queryParam comment Комментарий * @throws \Exception */ #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function changeStatusByModel(int $modelID, int $id): ResourceResponse { $result = $this->paymentService->setUserID(auth()->id()) ->changeStatusByModel( $id, \request()->get('move_to'), \request()->get('comment', ''), ); return new ResourceResponse( data: $result, status: 200 ); } /** * Обновить существующий платеж * */ #[Group('payments')] #[OpenApiResponse(ResourceResponse::class)] public function update(int $modelID, int $id, Request $request): ResourceResponse { return new ResourceResponse( data: $this->paymentService->setUserID(auth()->id())->update($id, $request), status: 200 ); } public function updatePaymentsArticle(int $modelId, int $newArticleId, Request $request) { $paymentIds = $request->input('payment_ids'); $this->paymentService->updateArticle($modelId, $newArticleId, $paymentIds); } public function updatePaymentsProject(int $modelId, int $newProjectId, Request $request) { $paymentIds = $request->input('payment_ids'); $this->paymentService->updateProject($modelId, $newProjectId, $paymentIds); } /** * Удалить существующий платеж * */ #[Group('payments')] #[OpenApiResponse(MessageResponse::class)] public function delete(int $modelID, int $id): MessageResponse { $this->paymentService->setUserID(auth()->id())->delete($id); return new MessageResponse( message: 'Удалено', status: 200 ); } public function getPaymentsStatus(int $modelId): ResourceResponse { return new ResourceResponse( data: new PaymentsStatusResource([]), status: 200 ); } public function import(Request $request) { Excel::import(new PaymentImport(), $request->file('file')); } public function deleteDistributions($paymentId, $distributionId) { return PaymentDistribution::query()->where(['payment_id' => $paymentId, 'id' => $distributionId])->delete(); } public function getCountPayments($modelId,Request $request) { return $this->paymentService->getCountPayments($modelId,$request); } }