Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
UpdateAdminBalanceAction
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 2
272
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 / 36
0.00% covered (danger)
0.00%
0 / 1
240
1<?php
2
3declare(strict_types=1);
4
5namespace App\Action\Admin;
6
7use App\Domain\Admin\Service\AdminBalanceUpdateService;
8use App\Renderer\JsonRenderer;
9use InvalidArgumentException;
10use Psr\Http\Message\ResponseInterface;
11use Psr\Http\Message\ServerRequestInterface;
12
13final readonly class UpdateAdminBalanceAction
14{
15    public function __construct(
16        private JsonRenderer $renderer,
17        private AdminBalanceUpdateService $balanceUpdateService,
18    ) {}
19
20    /**
21     * @param ServerRequestInterface $request
22     * @param ResponseInterface $response
23     * @param array<string, string> $args
24     * @return ResponseInterface
25     */
26    public function __invoke(
27        ServerRequestInterface $request,
28        ResponseInterface $response,
29        array $args,
30    ): ResponseInterface {
31        $body = (array)$request->getParsedBody();
32
33        // Validate required fields
34        $userId = $body['userId'] ?? null;
35        $fundId = $body['fundId'] ?? null;
36        $transactionType = $body['transactionType'] ?? null;
37        $amount = $body['amount'] ?? null;
38        $effectiveDate = $body['effectiveDate'] ?? null;
39        $internalNote = $body['internalNote'] ?? null;
40        $notifyInvestor = $body['notifyInvestor'] ?? false;
41
42        if (!$userId || !is_numeric($userId)) {
43            throw new InvalidArgumentException('Valid user ID is required');
44        }
45
46        if (!$fundId || !is_string($fundId)) {
47            throw new InvalidArgumentException('Fund ID is required');
48        }
49
50        if (!$transactionType || !is_string($transactionType)) {
51            throw new InvalidArgumentException('Transaction type is required');
52        }
53
54        if (!$amount || !is_numeric($amount) || (float)$amount <= 0) {
55            throw new InvalidArgumentException('Valid positive amount is required');
56        }
57
58        if (!$effectiveDate || !is_string($effectiveDate)) {
59            throw new InvalidArgumentException('Effective date is required');
60        }
61
62        if (!$internalNote || !is_string($internalNote) || trim($internalNote) === '') {
63            throw new InvalidArgumentException('Internal note is required');
64        }
65
66        // Get admin user ID from JWT
67        $adminUserId = (int)$request->getAttribute('userId');
68
69        // Adjust balance
70        $result = $this->balanceUpdateService->adjustBalance(
71            userId: (int)$userId,
72            fundId: $fundId,
73            transactionType: $transactionType,
74            amount: (string)$amount,
75            effectiveDate: $effectiveDate,
76            internalNote: $internalNote,
77            adminUserId: $adminUserId,
78            notifyInvestor: (bool)$notifyInvestor,
79        );
80
81        return $this->renderer->json($response, [
82            'success' => true,
83            'message' => 'Balance adjusted successfully',
84            'data' => $result,
85        ], 201);
86    }
87}