Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
50.67% covered (warning)
50.67%
38 / 75
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
LoanData
50.67% covered (warning)
50.67%
38 / 75
66.67% covered (warning)
66.67%
2 / 3
4.08
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromRow
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
1 / 1
1
 toArray
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace App\Domain\Loan\Data;
6
7use App\Support\Row;
8
9/**
10 * Represents a comprehensive data transfer object for loan information including investor details, account data, and loan terms.
11 *
12 * This immutable value object encapsulates all relevant information about a loan, including associated investor and account details,
13 * financial terms, payment schedules, and timestamps for various lifecycle events. All properties are nullable to accommodate
14 * partial data scenarios.
15 */
16final readonly class LoanData
17{
18    public function __construct(
19        public ?int $loanId = null,
20        public ?int $accountId = null,
21        public ?int $investorId = null,
22        public ?string $investorName = null,
23        public ?string $investorEmail = null,
24        public ?string $accountNumber = null,
25        public ?string $accountBalance = null,
26        public ?string $loanType = null,
27        public ?string $principleAmount = null,
28        public ?string $outstandingBalance = null,
29        public ?string $interestRate = null,
30        public ?string $servicingFeeRate = null,
31        public ?int $termMonths = null,
32        public ?string $monthlyPayment = null,
33        public ?string $totalInterest = null,
34        public ?string $totalServicing = null,
35        public ?string $totalRepayment = null,
36        public ?string $startDate = null,
37        public ?string $maturityDate = null,
38        public ?string $nextPaymentDue = null,
39        public ?string $status = null,
40        public ?string $requestedAmount = null,
41        public ?int $requestedTermMonths = null,
42        public ?string $collateralDescription = null,
43        public ?string $requestedAt = null,
44        public ?string $reviewedAt = null,
45        public ?int $reviewedBy = null,
46        public ?string $activatedAt = null,
47        public ?string $denialReason = null,
48        public ?string $approvalNotes = null,
49        public ?string $acceptedAt = null,
50        public ?string $declinedAt = null,
51        public ?string $declineReason = null,
52        public ?string $createdAt = null,
53        public ?string $updatedAt = null,
54    ) {}
55
56    /**
57     * @param array<mixed> $row
58     */
59    public static function fromRow(array $row): self
60    {
61        return new self(
62            loanId: Row::nullableInt($row, 'loanId'),
63            accountId: Row::nullableInt($row, 'accountId'),
64            investorId: Row::nullableInt($row, 'investorId'),
65            investorName: Row::nullableString($row, 'investorName'),
66            investorEmail: Row::nullableString($row, 'investorEmail'),
67            accountNumber: Row::nullableString($row, 'accountNumber'),
68            accountBalance: Row::nullableString($row, 'accountBalance'),
69            loanType: Row::nullableString($row, 'loanType'),
70            principleAmount: Row::nullableString($row, 'principleAmount'),
71            outstandingBalance: Row::nullableString($row, 'outstandingBalance'),
72            interestRate: Row::nullableString($row, 'interestRate'),
73            servicingFeeRate: Row::nullableString($row, 'servicingFeeRate'),
74            termMonths: Row::nullableInt($row, 'termMonths'),
75            monthlyPayment: Row::nullableString($row, 'monthlyPayment'),
76            totalInterest: Row::nullableString($row, 'totalInterest'),
77            totalServicing: Row::nullableString($row, 'totalServicing'),
78            totalRepayment: Row::nullableString($row, 'totalRepayment'),
79            startDate: Row::nullableString($row, 'startDate'),
80            maturityDate: Row::nullableString($row, 'maturityDate'),
81            nextPaymentDue: Row::nullableString($row, 'nextPaymentDue'),
82            status: Row::nullableString($row, 'status'),
83            requestedAmount: Row::nullableString($row, 'requestedAmount'),
84            requestedTermMonths: Row::nullableInt($row, 'requestedTermMonths'),
85            collateralDescription: Row::nullableString($row, 'collateralDescription'),
86            requestedAt: Row::nullableString($row, 'requestedAt'),
87            reviewedAt: Row::nullableString($row, 'reviewedAt'),
88            reviewedBy: Row::nullableInt($row, 'reviewedBy'),
89            activatedAt: Row::nullableString($row, 'activatedAt'),
90            denialReason: Row::nullableString($row, 'denialReason'),
91            approvalNotes: Row::nullableString($row, 'approvalNotes'),
92            acceptedAt: Row::nullableString($row, 'acceptedAt'),
93            declinedAt: Row::nullableString($row, 'declinedAt'),
94            declineReason: Row::nullableString($row, 'declineReason'),
95            createdAt: Row::nullableString($row, 'createdAt'),
96            updatedAt: Row::nullableString($row, 'updatedAt'),
97        );
98    }
99
100    /**
101     * @return array<string, mixed>
102     */
103    public function toArray(): array
104    {
105        return array_filter([
106            'loanId' => $this->loanId,
107            'accountId' => $this->accountId,
108            'investorId' => $this->investorId,
109            'investorName' => $this->investorName,
110            'investorEmail' => $this->investorEmail,
111            'accountNumber' => $this->accountNumber,
112            'accountBalance' => $this->accountBalance,
113            'loanType' => $this->loanType,
114            'principleAmount' => $this->principleAmount,
115            'outstandingBalance' => $this->outstandingBalance,
116            'interestRate' => $this->interestRate,
117            'servicingFeeRate' => $this->servicingFeeRate,
118            'termMonths' => $this->termMonths,
119            'monthlyPayment' => $this->monthlyPayment,
120            'totalInterest' => $this->totalInterest,
121            'totalServicing' => $this->totalServicing,
122            'totalRepayment' => $this->totalRepayment,
123            'startDate' => $this->startDate,
124            'maturityDate' => $this->maturityDate,
125            'nextPaymentDue' => $this->nextPaymentDue,
126            'status' => $this->status,
127            'requestedAmount' => $this->requestedAmount,
128            'requestedTermMonths' => $this->requestedTermMonths,
129            'collateralDescription' => $this->collateralDescription,
130            'requestedAt' => $this->requestedAt,
131            'reviewedAt' => $this->reviewedAt,
132            'reviewedBy' => $this->reviewedBy,
133            'activatedAt' => $this->activatedAt,
134            'denialReason' => $this->denialReason,
135            'approvalNotes' => $this->approvalNotes,
136            'acceptedAt' => $this->acceptedAt,
137            'declinedAt' => $this->declinedAt,
138            'declineReason' => $this->declineReason,
139            'createdAt' => $this->createdAt,
140            'updatedAt' => $this->updatedAt,
141        ], static fn($value): bool => $value !== null);
142    }
143}