File "PaymentController.php"

Full Path: /var/www/html/back/app/Http/Controllers/Api/V1/PaymentController.php
File size: 7.74 KB
MIME-type: text/x-php
Charset: utf-8

<?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);
    }
}