Total Complexity | 54 |
Total Lines | 395 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like SepaTxInf often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SepaTxInf, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
30 | class SepaTxInf |
||
31 | { |
||
32 | use SepaHelper; |
||
33 | |||
34 | /** @var string Type (Sepa::CDD or Sepa::CCT) */ |
||
35 | protected string $type = ''; |
||
36 | /** @var string Full name (lastname, firstname; company name; ...) */ |
||
37 | protected string $strName = ''; |
||
38 | /** @var string IBAN */ |
||
39 | protected string $strIBAN = ''; |
||
40 | /** @var string BIC */ |
||
41 | protected string $strBIC = ''; |
||
42 | /** @var string Mandate identification (only debit) */ |
||
43 | protected string $strMandateId = ''; |
||
44 | /** @var string Date when the mandate identification signed (only debit) (format YYYY-MM-DD) */ |
||
45 | protected string $strDateOfSignature = ''; |
||
46 | /** @var string Ultimate debitor name (information purpose only) */ |
||
47 | protected string $strUltimateName = ''; |
||
48 | /** @var string Payment id */ |
||
49 | protected string $strPaymentId = ''; |
||
50 | /** @var string Description */ |
||
51 | protected string $strDescription = ''; |
||
52 | /** @var float Value of the transaction in EUR */ |
||
53 | protected float $dblValue = 0.0; |
||
54 | /** @var string purpose */ |
||
55 | protected string $strPurpose = ''; |
||
56 | |||
57 | /** |
||
58 | * Create transaction info. |
||
59 | * @param string $type (Sepa::CDD or Sepa::CCT) |
||
60 | */ |
||
61 | public function __construct(string $type) |
||
62 | { |
||
63 | // invalid type causes E_USER_ERROR |
||
64 | if ($this->isValidType($type)) { |
||
65 | $this->type = $type; |
||
66 | } |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Validate the object. |
||
71 | * > This method usually dont have to be called from outside. It is |
||
72 | * called, when an instance is added to a PPI! |
||
73 | * @return int Sepa::OK or error code |
||
74 | * @internal |
||
75 | */ |
||
76 | public function validate() : int |
||
77 | { |
||
78 | $iErr = $this->validateIBAN() | $this->validateBIC() | $this->validateMandatory(); |
||
79 | |||
80 | // create payment id if empty so far! |
||
81 | if (empty($this->strPaymentId)) { |
||
82 | $this->strPaymentId = ($this->type == Sepa::CDD ? self::createUID() : 'NOTPROVIDED'); |
||
83 | } |
||
84 | return $iErr; |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * Get the error message for given error code. |
||
89 | * Since a transaction info can contain multiple errors, the result may contain more than |
||
90 | * one message separated by a separator. <br> |
||
91 | * The separator can be specified to meet the needs of different output destinations. |
||
92 | * Default value is a linefeed. |
||
93 | * @param int $iError the errorcode |
||
94 | * @param string $strLF Separator for multiple errors (default: PHP_EOL; posible values: '<br/>', ';', ...) |
||
95 | * @return string |
||
96 | */ |
||
97 | public function errorMsg(int $iError, string $strLF = PHP_EOL) : string |
||
98 | { |
||
99 | // route to the Sepa class to get localized message |
||
100 | return Sepa::errorMsgTxInf($iError, $strLF); |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * Set properties through associative array. |
||
105 | * Example array: |
||
106 | * ```php |
||
107 | * $aPPI = [ |
||
108 | * 'strName' => '<name>', |
||
109 | * 'strIBAN' => '<IBAN>', |
||
110 | * 'strBIC' => '<BIC>', |
||
111 | * 'strMandateId' => '<MandateId>', |
||
112 | * 'strDateOfSignature' => '<DateOfSignature>', |
||
113 | * 'strDescription' => '<Description>', |
||
114 | * 'strUltimateName' => '<UltimateName>', |
||
115 | * 'strPaymentId' => '<PaymentId>', |
||
116 | * 'strPurpose' => 'setPurpose', |
||
117 | * 'dblValue' => 123.4, |
||
118 | * ]; |
||
119 | * ``` |
||
120 | * The array does not have to contain all of the properties. Mandatory properties |
||
121 | * can be set later using the respective `setXXX()` method, optional ones can be left out. |
||
122 | * |
||
123 | * @param array<string,string|int|float> $aProperties see description |
||
124 | */ |
||
125 | public function fromArray(array $aProperties) : void |
||
126 | { |
||
127 | // use the setter methods to ensure that all validations are made! |
||
128 | $aPropertyMap = [ |
||
129 | 'strName' => 'setName', |
||
130 | 'strIBAN' => 'setIBAN', |
||
131 | 'strBIC' => 'setBIC', |
||
132 | 'strMandateId' => 'setMandateId', |
||
133 | 'strDateOfSignature' => 'setDateOfSignature', |
||
134 | 'strDescription' => 'setDescription', |
||
135 | 'strUltimateName' => 'setUltimateName', |
||
136 | 'strPaymentId' => 'setPaymentId', |
||
137 | 'strPurpose' => 'setPurpose', |
||
138 | ]; |
||
139 | foreach ($aPropertyMap as $strKey => $strFunc) { |
||
140 | if (isset($aProperties[$strKey])) { |
||
141 | $this->$strFunc($aProperties[$strKey]); |
||
142 | } |
||
143 | } |
||
144 | if (isset($aProperties['dblValue'])) { |
||
145 | $this->setValue(floatval($aProperties['dblValue'])); |
||
146 | } |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * Set full name (lastname, firstname; company name; ...). |
||
151 | * @param string $strName |
||
152 | */ |
||
153 | public function setName(string $strName) : void |
||
154 | { |
||
155 | $this->strName = self::validString($strName, Sepa::MAX70); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Set the IBAN. |
||
160 | * @param string $strIBAN |
||
161 | */ |
||
162 | public function setIBAN(string $strIBAN) : void |
||
163 | { |
||
164 | $this->strIBAN = $strIBAN; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Set the BIC. |
||
169 | * @param string $strBIC |
||
170 | */ |
||
171 | public function setBIC(string $strBIC) : void |
||
172 | { |
||
173 | $this->strBIC = $strBIC; |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * Set the mandate identification (only CDD). |
||
178 | * @param string $strMandateId |
||
179 | */ |
||
180 | public function setMandateId(string $strMandateId) : void |
||
181 | { |
||
182 | $this->strMandateId = self::validString($strMandateId, Sepa::ID2); |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * Set the date when the mandate identification signed (only CDD). |
||
187 | * @param \DateTime|int|string $DateOfSignature may be string (format YYYY-MM-DD), int (unixtimestamp) or DateTime - object |
||
188 | */ |
||
189 | public function setDateOfSignature($DateOfSignature) : void |
||
190 | { |
||
191 | if (is_object($DateOfSignature) && get_class($DateOfSignature) == 'DateTime') { |
||
192 | // DateTime -object |
||
193 | $this->strDateOfSignature = $DateOfSignature->format('Y-m-d'); |
||
194 | } else if (is_numeric($DateOfSignature)) { |
||
195 | $this->strDateOfSignature = date('Y-m-d', intval($DateOfSignature)); |
||
196 | } else if (is_string($DateOfSignature)) { |
||
197 | $this->strDateOfSignature = $DateOfSignature; |
||
198 | } |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Set ultimate debitor name (optional - information purpose only) |
||
203 | * @param string $strUltimateName |
||
204 | */ |
||
205 | public function setUltimateName(string $strUltimateName) : void |
||
206 | { |
||
207 | $this->strUltimateName = self::validString($strUltimateName, Sepa::MAX70); |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Set the payment id (only CDD). |
||
212 | * If no payment ID set, an unique ID is created internaly. |
||
213 | * @param string $strPaymentId |
||
214 | */ |
||
215 | public function setPaymentId(string $strPaymentId) : void |
||
216 | { |
||
217 | $strPaymentId = self::validString($strPaymentId, Sepa::ID1); |
||
218 | if (empty($strPaymentId)) { |
||
219 | $strPaymentId = ($this->type == Sepa::CDD ? self::createUID() : 'NOTPROVIDED'); |
||
220 | } |
||
221 | $this->strPaymentId = $strPaymentId; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Set the description. |
||
226 | * @param string $strDescription |
||
227 | */ |
||
228 | public function setDescription(string $strDescription) : void |
||
229 | { |
||
230 | $this->strDescription = self::validString($strDescription, Sepa::MAX140); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * Set the purpose. |
||
235 | * The purpose is an optional value! |
||
236 | * If set, only ISO 20022 codes of the ExternalPurpose1Code list are allowed. |
||
237 | * Referr to the actual list that is available in worksheet '11-Purpose 'of the Excel |
||
238 | * file provided in the download at |
||
239 | * [www.iso20022.org](https://www.iso20022.org/catalogue-messages/additional-content-messages/external-code-sets) |
||
240 | * > <b>Attention:</b><br> |
||
241 | * > There is no validation whether in this module nor through the provided XSD schemas for |
||
242 | * this value. To avoid rejection of your data, you have to take care for valid values on your own. |
||
243 | * @link ./Transaction-Purpose-Codes |
||
244 | * @param string $strPurpose |
||
245 | */ |
||
246 | public function setPurpose(string $strPurpose) : void |
||
247 | { |
||
248 | $this->strPurpose = strtoupper(substr($strPurpose, 0, 4)); |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * Set the value (amount) of the transaction. |
||
253 | * @param float $dblValue |
||
254 | */ |
||
255 | public function setValue(float $dblValue) : void |
||
256 | { |
||
257 | $this->dblValue = $dblValue; |
||
258 | } |
||
259 | |||
260 | /** |
||
261 | * Return the transaction type. |
||
262 | * @return string (Sepa::CDD or Sepa::CCT) |
||
263 | */ |
||
264 | public function getType() : string |
||
265 | { |
||
266 | return $this->type; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Get the full name (lastname, firstname; company name; ...). |
||
271 | * @return string |
||
272 | */ |
||
273 | public function getName() : string |
||
274 | { |
||
275 | return $this->strName; |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * Get the IBAN. |
||
280 | * @return string |
||
281 | */ |
||
282 | public function getIBAN() : string |
||
283 | { |
||
284 | return $this->strIBAN; |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Get the BIC. |
||
289 | * @return string |
||
290 | */ |
||
291 | public function getBIC() : string |
||
292 | { |
||
293 | return $this->strBIC; |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * Get the mandate identification. |
||
298 | * @return string |
||
299 | */ |
||
300 | public function getMandateId() : string |
||
301 | { |
||
302 | return $this->strMandateId; |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * Return the date when the mandate identification signed. |
||
307 | * @return string (format YYYY-MM-DD) |
||
308 | */ |
||
309 | public function getDateOfSignature() : string |
||
310 | { |
||
311 | return $this->strDateOfSignature; |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * Get the ultimate debitor name. |
||
316 | * @return string |
||
317 | */ |
||
318 | public function getUltimateName() : string |
||
319 | { |
||
320 | return $this->strUltimateName; |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * Get the payment id. |
||
325 | * This ID can be created internaly. |
||
326 | * @return string |
||
327 | */ |
||
328 | public function getPaymentId() : string |
||
329 | { |
||
330 | return $this->strPaymentId; |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * Get the description. |
||
335 | * @return string |
||
336 | */ |
||
337 | public function getDescription() : string |
||
338 | { |
||
339 | return $this->strDescription; |
||
340 | } |
||
341 | |||
342 | /** |
||
343 | * Get the purpose. |
||
344 | * @return string |
||
345 | */ |
||
346 | public function getPurpose() : string |
||
347 | { |
||
348 | return $this->strPurpose; |
||
349 | } |
||
350 | |||
351 | /** |
||
352 | * Get the value of the transaction. |
||
353 | * @return float |
||
354 | */ |
||
355 | public function getValue() : float |
||
356 | { |
||
357 | return $this->dblValue; |
||
358 | } |
||
359 | |||
360 | /** |
||
361 | * Validate IBAN |
||
362 | * @return int |
||
363 | */ |
||
364 | private function validateIBAN() : int |
||
365 | { |
||
366 | $iErr = Sepa::OK; |
||
367 | if (!Sepa::checkValidation(Sepa::V_NO_IBAN_VALIDATION)) { |
||
368 | if (strlen($this->strIBAN) == 0) { |
||
369 | $iErr |= Sepa::ERR_TX_IBAN_MISSING; |
||
370 | } else if (Sepa::validateIBAN($this->strIBAN) != Sepa::OK) { |
||
371 | $iErr |= Sepa::ERR_TX_INVALID_IBAN; |
||
372 | } |
||
373 | } |
||
374 | return $iErr; |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * Validate BIC |
||
379 | * @return int |
||
380 | */ |
||
381 | private function validateBIC() : int |
||
382 | { |
||
383 | $iErr = Sepa::OK; |
||
384 | if (!Sepa::checkValidation(Sepa::V_NO_BIC_VALIDATION)) { |
||
385 | if (strlen($this->strBIC) == 0) { |
||
386 | $iErr |= Sepa::ERR_TX_BIC_MISSING; |
||
387 | } else if (Sepa::validateBIC($this->strBIC) != Sepa::OK) { |
||
388 | $iErr |= Sepa::ERR_TX_INVALID_BIC; |
||
389 | } |
||
390 | } |
||
391 | return $iErr; |
||
392 | } |
||
393 | |||
394 | /** |
||
395 | * Validate mandatory properties |
||
396 | * @return int |
||
397 | */ |
||
398 | private function validateMandatory() : int |
||
425 | } |
||
426 | } |