File "ArticleController.php"
Full Path: /var/www/html/back/app/Http/Controllers/Api/V1/ArticleController.php
File size: 7.19 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\Article\Enums\ArticleTypeEnum;
use App\Domain\Article\Requests\CreateArticleRequest;
use App\Domain\Article\Requests\GetArticleListRequest;
use App\Domain\Article\Requests\UpdateArticleRequest;
use App\Domain\Article\Services\ArticleService;
use App\Http\Controllers\Api\ApiController;
use App\Imports\ArticleImport;
use App\Models\Article;
use App\Models\Payment;
use App\Responses\ResponseDto;
use Illuminate\Http\Request;
use Knuckles\Scribe\Attributes\Group;
use Maatwebsite\Excel\Facades\Excel;
/**
* Контроллер для управления статьями.
*/
class ArticleController extends ApiController
{
protected ArticleService $articleService;
public function __construct(ArticleService $articleService)
{
$this->articleService = $articleService;
}
/**
* Получить список всех статей.
*
* @queryParam search string Поисковый запрос для фильтрации статей. Пример: "Laravel"
* @queryParam article_group_id int ID категории для фильтрации статей. Пример: 3
* @queryParam article_type string Тип статьи, debit, credit
* @queryParam payment_id int ID платежа
* */
#[Group('articles')]
#[OpenApiResponse(Article::class)]
public function index(int $modelID, GetArticleListRequest $request): ResponseDto
{
return new ResponseDto(
data: $this->articleService->getAll($modelID, $request)->get(),
status: true
);
}
/**
* Получить список всех статей с платежами
*
* @queryParam search string Поисковый запрос для фильтрации статей. Пример: "Laravel"
* @queryParam article_group_id int ID категории для фильтрации статей. Пример: 3
* @queryParam article_type string Тип статьи, debit, credit
* @queryParam payment_id int ID платежа
* */
#[Group('articles')]
#[OpenApiResponse(Article::class)]
public function articlesWithPayments(int $modelID, GetArticleListRequest $request): ResponseDto
{
$result = [];
$this->articleService->getAll($modelID, $request)->with('payments')->with('payments')
->each(function ($item) use (&$result): void {
$amount = 0;
foreach ($item->payments as $payment) {
$amount += $payment->amount;
}
/** @var Article $item */
$item->forceFill([
'payments_amount' => $amount
]);
$result[] = $item;
});
return new ResponseDto(
data: $result,
status: true
);
}
/**
* Получить статью по ID.
*
*/
#[Group('articles')]
#[OpenApiResponse(Article::class)]
public function show(int $modelID, int $id): ResponseDto
{
return new ResponseDto(
data: $this->articleService->findById($id),
status: true
);
}
/**
* Сумма платежей по статье
*/
#[Group('articles')]
#[OpenApiResponse(Article::class)]
public function payments(int $modelID, int $id): ResponseDto
{
return new ResponseDto(
data: ['sum' => $this->articleService->payments($id)],
status: true
);
}
/**
* Создать новую статью.
*/
#[Group('articles')]
#[OpenApiResponse(Article::class)]
public function store(int $modelID, CreateArticleRequest $request): ResponseDto
{
return new ResponseDto(
data: $this->articleService->create($modelID, $request),
status: true
);
}
/**
* Обновить существующую статью.
*
* @param int $id
*/
#[Group('articles')]
#[OpenApiResponse(Article::class)]
public function update(int $modelID, int $id, UpdateArticleRequest $request): ResponseDto
{
return new ResponseDto(
status: (bool)$this->articleService->update($id, $request)
);
}
/**
* Удалить статью.
*
* @queryParam new_article_id int - ID статьи для переноса платежей (опционально)
* @param int $id
*/
#[Group('articles')]
#[OpenApiResponse(ResponseDto::class)]
public function destroy(int $modelID, int $id, Request $request): ResponseDto
{
return new ResponseDto(
status: (bool)$this->articleService->delete($id, $request->get('new_article_id', null))
);
}
/**
* Таб по статьям
*/
#[Group('articles')]
#[OpenApiResponse(ResponseDto::class)]
public function groupedList(int $modelID, GetArticleListRequest $request): ResponseDto
{
$articles = $this->articleService->getAll($modelID, $request)->with('payments')->get();
$result = [
'income' => [],
'outcome' => [],
];
$sum = [
'income' => 0,
'outcome' => 0,
];
/** @var Article $article */
foreach ($articles as $article) {
/** @var Payment $payment */
foreach ($article->payments as $payment) {
$key = ($article->article_type == ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value) ? 'income' : 'outcome';
if (!isset($result[$key][$article->id])) {
$result[$key][$article->id] = $article->toArray();
unset($result[$key][$article->id]['payments']);
$result[$key][$article->id] += [
'amount' => 0,
'limits' => $article->payment_limits
];
}
$result[$key][$article->id]['amount'] += $payment->amount;
$sum[$key] += $payment->amount;
}
}
return new ResponseDto(
data: [
'articles' => array_values($result),
'total' => $sum
],
status: true
);
}
public function import(Request $request)
{
Excel::import(new ArticleImport($request->input('type')), $request->file('file'));
}
/**
* Сделать статьей по умолчанию
*
* @param int $articleID
*/
#[Group('articles')]
#[OpenApiResponse(ResponseDto::class)]
public function setDefaultInProject(int $modelID, int $articleID): ResponseDto
{
return new ResponseDto(
status: (bool)$this->articleService->setDefault($articleID, true)
);
}
/**
* Убрать статью по умолчанию
*
* @param int $articleID
*/
#[Group('articles')]
#[OpenApiResponse(ResponseDto::class)]
public function unsetDefaultInProject(int $modelID, int $articleID): ResponseDto
{
return new ResponseDto(
status: (bool)$this->articleService->setDefault($articleID, false)
);
}
}