Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
FundsUpdater
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 3
210
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
 updateFund
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 1
156
 archiveFund
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace App\Domain\Funds\Service;
6
7use App\Domain\Funds\Data\FundData;
8use App\Domain\Funds\Repository\FundsRepository;
9use InvalidArgumentException;
10use JsonException;
11
12final class FundsUpdater
13{
14    private const VALID_TYPES = [
15        'Private Equity',
16        'Credit',
17        'Real Assets',
18        'Real Estate',
19        'Hedge',
20        'Other',
21    ];
22
23    private const VALID_STATUSES = [
24        'Active',
25        'Raising',
26        'Closed',
27        'Coming Soon',
28    ];
29
30    public function __construct(
31        private readonly FundsRepository $repository,
32    ) {}
33
34    public function updateFund(
35        string $id,
36        string $name,
37        string $type,
38        string $status,
39        ?string $descriptionShort,
40        ?string $descriptionFull,
41        ?string $heroImageUrl,
42        ?string $aum,
43        ?string $targetReturn,
44        ?string $minInvestment,
45        ?string $managerName,
46        ?string $irEmail,
47        bool $published,
48        ?int $vintageYear,
49        ?string $fundLife,
50        ?string $geographicFocus,
51        ?string $targetIrr,
52        ?string $managementFeePct,
53        ?string $carriedInterestPct,
54        ?array $investmentHighlights,
55        ?string $riskFactors,
56        ?string $managerBio,
57        ?string $managerPhotoUrl,
58        ?string $irContactName,
59        ?string $irContactPhone,
60        ?string $nextDistributionDate,
61        ?string $liquidity,
62        ?string $heroImageAlt,
63    ): FundData {
64        $name = trim($name);
65        if ($name === '') {
66            throw new InvalidArgumentException('Fund name is required');
67        }
68
69        if (!in_array($type, self::VALID_TYPES, true)) {
70            throw new InvalidArgumentException('Invalid fund type');
71        }
72
73        if (!in_array($status, self::VALID_STATUSES, true)) {
74            throw new InvalidArgumentException('Invalid fund status');
75        }
76
77        if ($aum !== null && $aum !== '' && !is_numeric($aum)) {
78            throw new InvalidArgumentException('AUM must be a numeric string');
79        }
80
81        if ($minInvestment !== null && $minInvestment !== '' && !is_numeric($minInvestment)) {
82            throw new InvalidArgumentException('Min investment must be a numeric string');
83        }
84
85        $investmentHighlightsJson = null;
86        if ($investmentHighlights !== null) {
87            try {
88                $investmentHighlightsJson = json_encode(array_values($investmentHighlights), JSON_THROW_ON_ERROR);
89            } catch (JsonException) {
90                throw new InvalidArgumentException('Invalid investment highlights');
91            }
92        }
93
94        return $this->repository->updateFund(
95            $id,
96            $name,
97            $type,
98            $status,
99            $descriptionShort,
100            $descriptionFull,
101            $heroImageUrl,
102            $aum,
103            $targetReturn,
104            $minInvestment,
105            $managerName,
106            $irEmail,
107            $published,
108            $vintageYear,
109            $fundLife,
110            $geographicFocus,
111            $targetIrr,
112            $managementFeePct,
113            $carriedInterestPct,
114            $investmentHighlightsJson,
115            $riskFactors,
116            $managerBio,
117            $managerPhotoUrl,
118            $irContactName,
119            $irContactPhone,
120            $nextDistributionDate,
121            $liquidity,
122            $heroImageAlt,
123        );
124    }
125
126    public function archiveFund(string $id): FundData
127    {
128        return $this->repository->archiveFund($id);
129    }
130}