Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
CreateAdminTransactionAction
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 2
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __invoke
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2
3declare(strict_types=1);
4
5namespace App\Action\Admin;
6
7use App\Domain\Exception\BadRequestException;
8use App\Domain\Exception\ValidationException;
9use App\Domain\Transaction\Service\TransactionService;
10use App\Renderer\JsonRenderer;
11use App\Support\Row;
12use Psr\Http\Message\ResponseInterface;
13use Psr\Http\Message\ServerRequestInterface;
14
15final readonly class CreateAdminTransactionAction
16{
17    public function __construct(
18        private JsonRenderer $renderer,
19        private TransactionService $transactionService,
20    ) {}
21
22    /**
23     * @param ServerRequestInterface $request
24     * @param ResponseInterface $response
25     * @param array<string, string> $args
26     * @return ResponseInterface
27     */
28    public function __invoke(
29        ServerRequestInterface $request,
30        ResponseInterface $response,
31        array $args,
32    ): ResponseInterface {
33        $accountId = (int)$args['accountId'];
34        $body = (array)$request->getParsedBody();
35
36        // Validate required fields
37        $transactionType = Row::nullableString($body, 'transactionType');
38        $amount = Row::nullableString($body, 'amount');
39        $description = Row::nullableString($body, 'description');
40
41        if ($transactionType === null || $transactionType === '') {
42            throw new BadRequestException('Transaction type is required');
43        }
44
45        if ($amount === null || $amount === '') {
46            throw new BadRequestException('Amount is required');
47        }
48
49        // Validate transaction type
50        $validTypes = ['investment', 'withdrawal', 'interest', 'fee'];
51        if (!in_array($transactionType, $validTypes, true)) {
52            throw new ValidationException(
53                'Invalid transaction type. Must be one of: ' . implode(', ', $validTypes)
54            );
55        }
56
57        // Validate amount is positive
58        if ((float)$amount <= 0) {
59            throw new ValidationException('Amount must be greater than zero');
60        }
61
62        // Create the transaction
63        $transaction = $this->transactionService->createTransaction(
64            accountId: $accountId,
65            transactionType: $transactionType,
66            amount: $amount,
67            description: $description,
68        );
69
70        return $this->renderer->json($response, [
71            'success' => true,
72            'message' => ucfirst($transactionType) . ' recorded successfully',
73            'data' => $transaction,
74        ], 201);
75    }
76}