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
TaxRulesApiController
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\TaxRuleDto;
12use App\Modules\Tax\Application\Service\TaxApplicationService;
13use App\Modules\Tax\Domain\Model\TaxRule;
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 determination rules.
22 */
23final readonly class TaxRulesApiController
24{
25    use ApiResponseTrait;
26
27    /**
28     * TaxRulesApiController constructor.
29     */
30    public function __construct(
31        private TaxApplicationService $taxService,
32        private Psr17Factory $psr17Factory,
33    ) {
34    }
35
36    /**
37     * List all determination rules (GET /api/v1/tax/rules).
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        $rules = $this->taxService->getTaxRules($filters);
49        $data = array_map(static fn(TaxRule $r): array => $r->toArray(), $rules);
50
51        return $this->jsonResponse($this->psr17Factory, ['success' => true, 'data' => $data]);
52    }
53
54    /**
55     * Get single rule (GET /api/v1/tax/rules/{id:\d+}).
56     */
57    public function detail(ServerRequestInterface $request): ResponseInterface
58    {
59        $id = (int) ($request->getAttribute('id') ?? 0);
60        $rule = $this->taxService->getTaxRule($id);
61
62        if ($rule === null) {
63            return $this->jsonResponse(
64                $this->psr17Factory,
65                ['success' => false, 'error' => 'Tax rule not found.'],
66                404
67            );
68        }
69
70        return $this->jsonResponse($this->psr17Factory, ['success' => true, 'data' => $rule->toArray()]);
71    }
72
73    /**
74     * Create determination rule (POST /api/v1/tax/rules).
75     */
76    public function create(ServerRequestInterface $request): ResponseInterface
77    {
78        $body = $this->parseJsonBody($request);
79
80        try {
81            $dto = TaxRuleDto::fromArray($body);
82            $saved = $this->taxService->saveTaxRule($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 determination rule (PUT /api/v1/tax/rules/{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 = TaxRuleDto::fromArray($body, $id);
108            $saved = $this->taxService->saveTaxRule($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 determination rule (DELETE /api/v1/tax/rules/{id:\d+}).
122     */
123    public function delete(ServerRequestInterface $request): ResponseInterface
124    {
125        $id = (int) ($request->getAttribute('id') ?? 0);
126        $success = $this->taxService->deleteTaxRule($id);
127
128        return $this->jsonResponse($this->psr17Factory, ['success' => $success]);
129    }
130}