1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace Genkgo\Camt\Decoder; |
||||
6 | |||||
7 | use Genkgo\Camt\Decoder\Factory\DTO as DTOFactory; |
||||
8 | use Genkgo\Camt\DTO; |
||||
9 | use Genkgo\Camt\DTO\RelatedParty; |
||||
10 | use Genkgo\Camt\DTO\RelatedPartyTypeInterface; |
||||
11 | use Genkgo\Camt\Util\MoneyFactory; |
||||
12 | use SimpleXMLElement; |
||||
13 | |||||
14 | abstract class EntryTransactionDetail |
||||
15 | { |
||||
16 | private DateDecoderInterface $dateDecoder; |
||||
17 | |||||
18 | private MoneyFactory $moneyFactory; |
||||
19 | |||||
20 | /** |
||||
21 | * EntryTransactionDetail constructor. |
||||
22 | */ |
||||
23 | public function __construct(DateDecoderInterface $dateDecoder) |
||||
24 | { |
||||
25 | 40 | $this->dateDecoder = $dateDecoder; |
|||
26 | $this->moneyFactory = new MoneyFactory(); |
||||
27 | 40 | } |
|||
28 | 40 | ||||
29 | public function addCreditDebitIdentifier(DTO\EntryTransactionDetail $detail, SimpleXMLElement $CdtDbtInd): void |
||||
30 | 24 | { |
|||
31 | $creditDebitIdentifier = (string) $CdtDbtInd; |
||||
32 | 24 | $creditDebitIdentifier = in_array($creditDebitIdentifier, ['CRDT', 'DBIT'], true) |
|||
33 | 8 | ? $creditDebitIdentifier |
|||
34 | : null; |
||||
35 | $detail->setCreditDebitIndicator($creditDebitIdentifier); |
||||
36 | 19 | } |
|||
37 | 19 | ||||
38 | public function addReference(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||||
39 | 19 | { |
|||
40 | 19 | if (false === isset($xmlDetail->Refs)) { |
|||
41 | 19 | return; |
|||
42 | 19 | } |
|||
43 | 19 | ||||
44 | 19 | $refs = $xmlDetail->Refs; |
|||
45 | 19 | $reference = new DTO\Reference(); |
|||
46 | 19 | ||||
47 | 19 | $reference->setMessageId(isset($refs->MsgId) ? (string) $refs->MsgId : null); |
|||
48 | 19 | $reference->setAccountServicerReference(isset($refs->AcctSvcrRef) ? (string) $refs->AcctSvcrRef : null); |
|||
49 | 19 | $reference->setPaymentInformationId(isset($refs->PmtInfId) ? (string) $refs->PmtInfId : null); |
|||
50 | 19 | $reference->setInstructionId(isset($refs->InstrId) ? (string) $refs->InstrId : null); |
|||
51 | 19 | $reference->setEndToEndId(isset($refs->EndToEndId) ? (string) $refs->EndToEndId : null); |
|||
52 | $reference->setUuidEndToEndReference(isset($refs->UETR) ? (string) $refs->UETR : null); |
||||
53 | 19 | $reference->setTransactionId(isset($refs->TxId) ? (string) $refs->TxId : null); |
|||
54 | 9 | $reference->setMandateId(isset($refs->MndtId) ? (string) $refs->MndtId : null); |
|||
55 | 9 | $reference->setChequeNumber(isset($refs->ChqNb) ? (string) $refs->ChqNb : null); |
|||
56 | $reference->setClearingSystemReference(isset($refs->ClrSysRef) ? (string) $refs->ClrSysRef : null); |
||||
57 | 9 | $reference->setAccountOwnerTransactionId(isset($refs->AcctOwnrTxId) ? (string) $refs->AcctOwnrTxId : null); |
|||
58 | $reference->setAccountServicerTransactionId(isset($refs->AcctSvcrTxId) ? (string) $refs->AcctSvcrTxId : null); |
||||
59 | $reference->setMarketInfrastructureTransactionId(isset($refs->MktInfrstrctrTxId) ? (string) $refs->MktInfrstrctrTxId : null); |
||||
60 | 19 | $reference->setProcessingId(isset($refs->PrcgId) ? (string) $refs->PrcgId : null); |
|||
61 | 19 | ||||
62 | foreach ($refs->Prtry as $xmlProprietary) { |
||||
63 | 24 | $type = isset($xmlProprietary->Tp) ? (string) $xmlProprietary->Tp : null; |
|||
64 | $subReference = isset($xmlProprietary->Ref) ? (string) $xmlProprietary->Ref : null; |
||||
65 | 24 | ||||
66 | 1 | $reference->addProprietary(new DTO\ProprietaryReference($type, $subReference)); |
|||
67 | } |
||||
68 | |||||
69 | $detail->setReference($reference); |
||||
70 | 23 | } |
|||
71 | 23 | ||||
72 | 23 | public function addRelatedParties(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
|||
73 | 23 | { |
|||
74 | 23 | if (false === isset($xmlDetail->RltdPties)) { |
|||
75 | 23 | return; |
|||
76 | } |
||||
77 | 23 | ||||
78 | /** @var SimpleXMLElement $xmlRelatedParty */ |
||||
79 | foreach ($xmlDetail->RltdPties as $xmlRelatedParty) { |
||||
80 | 23 | if (isset($xmlRelatedParty->Cdtr)) { |
|||
81 | 5 | $xmlRelatedPartyType = $xmlRelatedParty->Cdtr; |
|||
82 | 5 | $xmlRelatedPartyTypeAccount = $xmlRelatedParty->CdtrAcct; |
|||
83 | 5 | ||||
84 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\Creditor::class, $xmlRelatedPartyTypeAccount); |
||||
85 | 5 | } |
|||
86 | |||||
87 | if (isset($xmlRelatedParty->UltmtCdtr)) { |
||||
88 | 23 | $xmlRelatedPartyType = $xmlRelatedParty->UltmtCdtr; |
|||
89 | 20 | ||||
90 | 20 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\UltimateCreditor::class); |
|||
91 | 20 | } |
|||
92 | 20 | ||||
93 | if (isset($xmlRelatedParty->Dbtr)) { |
||||
94 | 20 | $xmlRelatedPartyType = $xmlRelatedParty->Dbtr; |
|||
95 | $xmlRelatedPartyTypeAccount = $xmlRelatedParty->DbtrAcct; |
||||
96 | |||||
97 | 23 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\Debtor::class, $xmlRelatedPartyTypeAccount); |
|||
98 | 5 | } |
|||
99 | 5 | ||||
100 | 5 | if (isset($xmlRelatedParty->UltmtDbtr)) { |
|||
101 | $xmlRelatedPartyType = $xmlRelatedParty->UltmtDbtr; |
||||
102 | 5 | ||||
103 | $this->addRelatedParty($detail, $xmlRelatedPartyType, DTO\UltimateDebtor::class); |
||||
104 | } |
||||
105 | 23 | } |
|||
106 | } |
||||
107 | 23 | ||||
108 | /** |
||||
109 | 23 | * @param class-string<RelatedPartyTypeInterface> $relatedPartyTypeClass |
|||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||||
110 | 23 | */ |
|||
111 | protected function addRelatedParty(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlRelatedPartyType, string $relatedPartyTypeClass, ?SimpleXMLElement $xmlRelatedPartyTypeAccount = null): void |
||||
112 | { |
||||
113 | 23 | // CAMT v08 uses substructure, so we check for its existence or fallback to the element itself to keep compatibility with CAMT v04 |
|||
114 | $xmlPartyDetail = $xmlRelatedPartyType->Pty ?: $xmlRelatedPartyType->Agt?->FinInstnId ?: $xmlRelatedPartyType; |
||||
115 | 23 | ||||
116 | $xmlRelatedPartyName = (isset($xmlPartyDetail->Nm)) ? (string) $xmlPartyDetail->Nm : null; |
||||
117 | 23 | $relatedPartyType = new $relatedPartyTypeClass($xmlRelatedPartyName); |
|||
118 | |||||
119 | if (isset($xmlPartyDetail->PstlAdr)) { |
||||
120 | 22 | $relatedPartyType->setAddress(DTOFactory\Address::createFromXml($xmlPartyDetail->PstlAdr)); |
|||
121 | } |
||||
122 | 22 | ||||
123 | 14 | $relatedParty = new RelatedParty($relatedPartyType, $this->getRelatedPartyAccount($xmlRelatedPartyTypeAccount)); |
|||
124 | |||||
125 | $detail->addRelatedParty($relatedParty); |
||||
126 | 17 | } |
|||
127 | 17 | ||||
128 | 17 | public function addRelatedAgents(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
|||
129 | 17 | { |
|||
130 | 17 | if (false === isset($xmlDetail->RltdAgts)) { |
|||
131 | return; |
||||
132 | } |
||||
133 | 17 | ||||
134 | 17 | foreach ($xmlDetail->RltdAgts as $xmlRelatedAgent) { |
|||
135 | 17 | if (isset($xmlRelatedAgent->CdtrAgt)) { |
|||
136 | 17 | $agent = new DTO\CreditorAgent((string) $xmlRelatedAgent->CdtrAgt->FinInstnId->Nm, (string) $xmlRelatedAgent->CdtrAgt->FinInstnId->BIC); |
|||
137 | $relatedAgent = new DTO\RelatedAgent($agent); |
||||
138 | $detail->addRelatedAgent($relatedAgent); |
||||
139 | 17 | } |
|||
140 | |||||
141 | 25 | if (isset($xmlRelatedAgent->DbtrAgt)) { |
|||
142 | $agent = new DTO\DebtorAgent((string) $xmlRelatedAgent->DbtrAgt->FinInstnId->Nm, (string) $xmlRelatedAgent->DbtrAgt->FinInstnId->BIC); |
||||
143 | 25 | $relatedAgent = new DTO\RelatedAgent($agent); |
|||
144 | 8 | $detail->addRelatedAgent($relatedAgent); |
|||
145 | } |
||||
146 | } |
||||
147 | 20 | } |
|||
148 | 20 | ||||
149 | public function addRemittanceInformation(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||||
150 | { |
||||
151 | 20 | if (false === isset($xmlDetail->RmtInf)) { |
|||
152 | 20 | return; |
|||
153 | 20 | } |
|||
154 | 10 | ||||
155 | 10 | $remittanceInformation = new DTO\RemittanceInformation(); |
|||
156 | $unstructuredBlockExists = false; |
||||
157 | |||||
158 | 10 | // Unstructured blocks |
|||
159 | $xmlDetailsUnstructuredBlocks = $xmlDetail->RmtInf->Ustrd; |
||||
160 | if ($xmlDetailsUnstructuredBlocks !== null) { |
||||
161 | 10 | foreach ($xmlDetailsUnstructuredBlocks as $xmlDetailsUnstructuredBlock) { |
|||
162 | 10 | $unstructuredRemittanceInformation = new DTO\UnstructuredRemittanceInformation( |
|||
163 | 10 | (string) $xmlDetailsUnstructuredBlock |
|||
164 | 10 | ); |
|||
165 | |||||
166 | $remittanceInformation->addUnstructuredBlock($unstructuredRemittanceInformation); |
||||
167 | |||||
168 | // Legacy : use the very first unstructured block |
||||
169 | if ($remittanceInformation->getMessage() === null) { |
||||
0 ignored issues
–
show
The function
Genkgo\Camt\DTO\Remittan...formation::getMessage() has been deprecated: Use getStructuredBlocks method instead
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
170 | $unstructuredBlockExists = true; |
||||
171 | 20 | $remittanceInformation->setMessage( |
|||
0 ignored issues
–
show
The function
Genkgo\Camt\DTO\Remittan...formation::setMessage() has been deprecated: Use addStructuredBlock method instead
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
172 | 20 | (string) $xmlDetailsUnstructuredBlock |
|||
173 | 20 | ); |
|||
174 | 14 | } |
|||
175 | } |
||||
176 | 14 | } |
|||
177 | 4 | ||||
178 | 4 | // Strutcured blocks |
|||
179 | $xmlDetailsStructuredBlocks = $xmlDetail->RmtInf->Strd; |
||||
180 | if ($xmlDetailsStructuredBlocks !== null) { |
||||
181 | foreach ($xmlDetailsStructuredBlocks as $xmlDetailsStructuredBlock) { |
||||
182 | 14 | $structuredRemittanceInformation = new DTO\StructuredRemittanceInformation(); |
|||
183 | 14 | ||||
184 | if (isset($xmlDetailsStructuredBlock->AddtlRmtInf)) { |
||||
185 | 14 | $structuredRemittanceInformation->setAdditionalRemittanceInformation( |
|||
186 | 14 | (string) $xmlDetailsStructuredBlock->AddtlRmtInf |
|||
187 | 14 | ); |
|||
188 | } |
||||
189 | |||||
190 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf)) { |
||||
191 | 14 | $creditorReferenceInformation = new DTO\CreditorReferenceInformation(); |
|||
192 | |||||
193 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf->Ref)) { |
||||
194 | 4 | $creditorReferenceInformation->setRef( |
|||
195 | 4 | (string) $xmlDetailsStructuredBlock->CdtrRefInf->Ref |
|||
196 | ); |
||||
197 | } |
||||
198 | |||||
199 | 14 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf->Tp, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Prtry) |
|||
200 | |||||
201 | ) { |
||||
202 | 13 | $creditorReferenceInformation->setProprietary( |
|||
203 | 13 | (string) $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Prtry |
|||
204 | ); |
||||
205 | } |
||||
206 | |||||
207 | 14 | if (isset($xmlDetailsStructuredBlock->CdtrRefInf->Tp, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry, $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Cd) |
|||
208 | |||||
209 | ) { |
||||
210 | $creditorReferenceInformation->setCode( |
||||
211 | 14 | (string) $xmlDetailsStructuredBlock->CdtrRefInf->Tp->CdOrPrtry->Cd |
|||
212 | 14 | ); |
|||
213 | 14 | } |
|||
214 | |||||
215 | $structuredRemittanceInformation->setCreditorReferenceInformation($creditorReferenceInformation); |
||||
216 | |||||
217 | 14 | // Legacy : do not overwrite message if already defined above |
|||
218 | // and no creditor reference is already defined |
||||
219 | if (false === $unstructuredBlockExists |
||||
220 | && $remittanceInformation->getCreditorReferenceInformation() === null) { |
||||
221 | 20 | $remittanceInformation->setCreditorReferenceInformation($creditorReferenceInformation); |
|||
222 | 20 | } |
|||
223 | } |
||||
224 | 24 | ||||
225 | $remittanceInformation->addStructuredBlock($structuredRemittanceInformation); |
||||
226 | 24 | } |
|||
227 | 23 | } |
|||
228 | |||||
229 | $detail->setRemittanceInformation($remittanceInformation); |
||||
230 | 1 | } |
|||
231 | 1 | ||||
232 | 1 | public function addRelatedDates(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
|||
233 | { |
||||
234 | 1 | if (false === isset($xmlDetail->RltdDts)) { |
|||
235 | return; |
||||
236 | 1 | } |
|||
237 | |||||
238 | if (isset($xmlDetail->RltdDts->AccptncDtTm)) { |
||||
239 | $RelatedDates = DTO\RelatedDates::fromUnstructured( |
||||
240 | 24 | $this->dateDecoder->decode((string) $xmlDetail->RltdDts->AccptncDtTm) |
|||
241 | ); |
||||
242 | 24 | $detail->setRelatedDates($RelatedDates); |
|||
243 | 1 | ||||
244 | 1 | return; |
|||
245 | 1 | } |
|||
246 | } |
||||
247 | 1 | ||||
248 | public function addReturnInformation(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||||
249 | 24 | { |
|||
250 | if (isset($xmlDetail->RtrInf, $xmlDetail->RtrInf->Rsn->Cd)) { |
||||
251 | 24 | $remittanceInformation = DTO\ReturnInformation::fromUnstructured( |
|||
252 | (string) $xmlDetail->RtrInf->Rsn->Cd, |
||||
253 | 24 | (string) $xmlDetail->RtrInf->AddtlInf |
|||
254 | 1 | ); |
|||
255 | 1 | $detail->setReturnInformation($remittanceInformation); |
|||
256 | } |
||||
257 | 1 | } |
|||
258 | |||||
259 | 24 | public function addAdditionalTransactionInformation(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
|||
260 | { |
||||
261 | 22 | if (isset($xmlDetail->AddtlTxInf)) { |
|||
262 | $additionalInformation = new DTO\AdditionalTransactionInformation( |
||||
263 | 22 | (string) $xmlDetail->AddtlTxInf |
|||
264 | ); |
||||
265 | 22 | $detail->setAdditionalTransactionInformation($additionalInformation); |
|||
266 | 20 | } |
|||
267 | } |
||||
268 | 20 | ||||
269 | 20 | public function addBankTransactionCode(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
|||
270 | 20 | { |
|||
271 | 20 | $bankTransactionCode = new DTO\BankTransactionCode(); |
|||
272 | |||||
273 | if (isset($xmlDetail->BkTxCd)) { |
||||
274 | 20 | $bankTransactionCode = new DTO\BankTransactionCode(); |
|||
275 | |||||
276 | if (isset($xmlDetail->BkTxCd->Prtry)) { |
||||
277 | 20 | $proprietaryBankTransactionCode = new DTO\ProprietaryBankTransactionCode( |
|||
278 | 7 | (string) $xmlDetail->BkTxCd->Prtry->Cd, |
|||
279 | 7 | (string) $xmlDetail->BkTxCd->Prtry->Issr |
|||
280 | ); |
||||
281 | |||||
282 | 7 | $bankTransactionCode->setProprietary($proprietaryBankTransactionCode); |
|||
283 | 7 | } |
|||
284 | 7 | ||||
285 | 7 | if (isset($xmlDetail->BkTxCd->Domn)) { |
|||
286 | $domainBankTransactionCode = new DTO\DomainBankTransactionCode( |
||||
287 | (string) $xmlDetail->BkTxCd->Domn->Cd |
||||
288 | 7 | ); |
|||
289 | |||||
290 | if (isset($xmlDetail->BkTxCd->Domn->Fmly)) { |
||||
291 | 7 | $domainFamilyBankTransactionCode = new DTO\DomainFamilyBankTransactionCode( |
|||
292 | (string) $xmlDetail->BkTxCd->Domn->Fmly->Cd, |
||||
293 | (string) $xmlDetail->BkTxCd->Domn->Fmly->SubFmlyCd |
||||
294 | ); |
||||
295 | 22 | ||||
296 | 22 | $domainBankTransactionCode->setFamily($domainFamilyBankTransactionCode); |
|||
297 | } |
||||
298 | 24 | ||||
299 | $bankTransactionCode->setDomain($domainBankTransactionCode); |
||||
300 | 24 | } |
|||
301 | 4 | } |
|||
302 | |||||
303 | 4 | $detail->setBankTransactionCode($bankTransactionCode); |
|||
304 | 4 | } |
|||
305 | 4 | ||||
306 | public function addCharges(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail): void |
||||
307 | 4 | { |
|||
308 | if (isset($xmlDetail->Chrgs)) { |
||||
309 | $charges = new DTO\Charges(); |
||||
310 | 4 | ||||
311 | 4 | if (isset($xmlDetail->Chrgs->TtlChrgsAndTaxAmt) && (string) $xmlDetail->Chrgs->TtlChrgsAndTaxAmt) { |
|||
312 | $money = $this->moneyFactory->create($xmlDetail->Chrgs->TtlChrgsAndTaxAmt, null); |
||||
313 | |||||
314 | 4 | $charges->setTotalChargesAndTaxAmount($money); |
|||
315 | 4 | } |
|||
316 | |||||
317 | 4 | $chargesRecords = $xmlDetail->Chrgs->Rcrd; |
|||
318 | 4 | if ($chargesRecords !== null) { |
|||
319 | 4 | /** @var SimpleXMLElement $chargesRecord */ |
|||
320 | foreach ($chargesRecords as $chargesRecord) { |
||||
321 | 4 | $chargesDetail = new DTO\ChargesRecord(); |
|||
322 | 4 | ||||
323 | if (isset($chargesRecord->Amt) && (string) $chargesRecord->Amt) { |
||||
324 | $money = $this->moneyFactory->create($chargesRecord->Amt, $chargesRecord->CdtDbtInd); |
||||
325 | 4 | $chargesDetail->setAmount($money); |
|||
326 | } |
||||
327 | 4 | if (isset($chargesRecord->CdtDbtInd) && (string) $chargesRecord->CdtDbtInd === 'true') { |
|||
328 | $chargesDetail->setChargesIncludedIndicator(true); |
||||
329 | } |
||||
330 | 4 | if (isset($chargesRecord->Tp->Prtry->Id) && (string) $chargesRecord->Tp->Prtry->Id) { |
|||
331 | 4 | $chargesDetail->setIdentification((string) $chargesRecord->Tp->Prtry->Id); |
|||
332 | } |
||||
333 | 4 | $charges->addRecord($chargesDetail); |
|||
334 | } |
||||
335 | } |
||||
336 | 4 | $detail->setCharges($charges); |
|||
337 | } |
||||
338 | 24 | } |
|||
339 | |||||
340 | 23 | public function addAmountDetails(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail, SimpleXMLElement $CdtDbtInd): void |
|||
341 | { |
||||
342 | 23 | if (isset($xmlDetail->AmtDtls, $xmlDetail->AmtDtls->TxAmt, $xmlDetail->AmtDtls->TxAmt->Amt)) { |
|||
343 | 8 | $money = $this->moneyFactory->create($xmlDetail->AmtDtls->TxAmt->Amt, $CdtDbtInd); |
|||
344 | 8 | $detail->setAmountDetails($money); |
|||
345 | } |
||||
346 | 23 | } |
|||
347 | |||||
348 | 23 | public function addAmount(DTO\EntryTransactionDetail $detail, SimpleXMLElement $xmlDetail, SimpleXMLElement $CdtDbtInd): void |
|||
349 | { |
||||
350 | 23 | if (isset($xmlDetail->Amt)) { |
|||
351 | 15 | $money = $this->moneyFactory->create($xmlDetail->Amt, $CdtDbtInd); |
|||
352 | 15 | $detail->setAmount($money); |
|||
353 | } |
||||
354 | 23 | } |
|||
355 | |||||
356 | 16 | abstract public function getRelatedPartyAccount(?SimpleXMLElement $xmlRelatedPartyTypeAccount): ?DTO\Account; |
|||
357 | } |
||||
358 |