Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
TaxGroupsApiController
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
6 / 6
10
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 list
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 detail
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 create
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
2
 update
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
2
 delete
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Modules\Tax\Presentation\Api;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Modules\Tax\Application\DTO\TaxGroupDto;
12use App\Modules\Tax\Application\Service\TaxApplicationService;
13use App\Modules\Tax\Domain\Model\TaxGroup;
14use App\Shared\Infrastructure\Http\ApiResponseTrait;
15use Nyholm\Psr7\Factory\Psr17Factory;
16use Psr\Http\Message\ResponseInterface;
17use Psr\Http\Message\ServerRequestInterface;
18use Throwable;
19
20/**
21 * REST API controller for managing tax groups.
22 */
23final readonly class TaxGroupsApiController
24{
25    use ApiResponseTrait;
26
27    /**
28     * TaxGroupsApiController constructor.
29     */
30    public function __construct(
31        private TaxApplicationService $taxService,
32        private Psr17Factory $psr17Factory,
33    ) {
34    }
35
36    /**
37     * List all tax groups (GET /api/v1/tax/groups).
38     */
39    public function list(ServerRequestInterface $request): ResponseInterface
40    {
41        $params = $request->getQueryParams();
42        $filters = [];
43
44        if (isset($params['is_active'])) {
45            $filters['is_active'] = (int) $params['is_active'];
46        }
47
48        $groups = $this->taxService->getTaxGroups($filters);
49        $data = array_map(static fn(TaxGroup $g): array => $g->toArray(), $groups);
50
51        return $this->jsonResponse($this->psr17Factory, ['success' => true, 'data' => $data]);
52    }
53
54    /**
55     * Get single tax group (GET /api/v1/tax/groups/{id:\d+}).
56     */
57    public function detail(ServerRequestInterface $request): ResponseInterface
58    {
59        $id = (int) ($request->getAttribute('id') ?? 0);
60        $group = $this->taxService->getTaxGroup($id);
61
62        if ($group === null) {
63            return $this->jsonResponse(
64                $this->psr17Factory,
65                ['success' => false, 'error' => 'Tax group not found.'],
66                404
67            );
68        }
69
70        return $this->jsonResponse($this->psr17Factory, ['success' => true, 'data' => $group->toArray()]);
71    }
72
73    /**
74     * Create new tax group (POST /api/v1/tax/groups).
75     */
76    public function create(ServerRequestInterface $request): ResponseInterface
77    {
78        $body = $this->parseJsonBody($request);
79
80        try {
81            $dto = TaxGroupDto::fromArray($body);
82            $saved = $this->taxService->saveTaxGroup($dto);
83
84            return $this->jsonResponse(
85                $this->psr17Factory,
86                ['success' => true, 'data' => $saved->toArray()],
87                201
88            );
89        } catch (Throwable $e) {
90            return $this->jsonResponse(
91                $this->psr17Factory,
92                ['success' => false, 'error' => $e->getMessage()],
93                400
94            );
95        }
96    }
97
98    /**
99     * Update tax group (PUT /api/v1/tax/groups/{id:\d+}).
100     */
101    public function update(ServerRequestInterface $request): ResponseInterface
102    {
103        $id = (int) ($request->getAttribute('id') ?? 0);
104        $body = $this->parseJsonBody($request);
105
106        try {
107            $dto = TaxGroupDto::fromArray($body, $id);
108            $saved = $this->taxService->saveTaxGroup($dto);
109
110            return $this->jsonResponse($this->psr17Factory, ['success' => true, 'data' => $saved->toArray()]);
111        } catch (Throwable $e) {
112            return $this->jsonResponse(
113                $this->psr17Factory,
114                ['success' => false, 'error' => $e->getMessage()],
115                400
116            );
117        }
118    }
119
120    /**
121     * Delete tax group (DELETE /api/v1/tax/groups/{id:\d+}).
122     */
123    public function delete(ServerRequestInterface $request): ResponseInterface
124    {
125        $id = (int) ($request->getAttribute('id') ?? 0);
126        $success = $this->taxService->deleteTaxGroup($id);
127
128        return $this->jsonResponse($this->psr17Factory, ['success' => $success]);
129    }
130}