Passed
Branch develop (477450)
by JAIME ELMER
06:26
created

DataMap   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 390
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 127
dl 0
loc 390
rs 6
c 0
b 0
f 0
wmc 55

52 Methods

Rating   Name   Duplication   Size   Complexity  
A getTaxableAmount() 0 3 1
A getOperationType() 0 2 1
A setDocumentSeries() 0 3 1
A setSpecificFields() 0 10 2
A getCustomerAddress() 0 2 1
A getNoteAffectedDocType() 0 2 1
A getTotalAllowances() 0 5 1
A setCustomerAddress() 0 3 1
A getNoteType() 0 2 1
A setPurchaseOrder() 0 3 1
A getISC() 0 2 1
A getDueDate() 0 2 1
A setCustomerDocNumber() 0 3 1
A setOperationType() 0 3 1
A setAllowancesAndCharges() 0 3 1
A getTaxedAmount() 0 4 1
A getPayableAmount() 0 6 1
A setCustomerDocType() 0 3 1
A setDefaults() 0 3 3
A getBillName() 0 2 1
A getBillableValue() 0 2 1
A getItems() 0 2 1
A getRawItems() 0 2 1
A getNoteDescription() 0 2 1
A getTotalTaxableOperations() 0 2 1
A setDocumentNumber() 0 3 1
A getInvoiceId() 0 2 1
A getDocumentNumber() 0 2 1
A getIGV() 0 3 1
A getTotalFreeOperations() 0 2 1
A setDueDate() 0 3 1
A __construct() 0 22 1
A getNoteAffectedDocId() 0 2 1
A getCustomerDocType() 0 2 1
A getTotalUnaffectedOperations() 0 3 1
A getTotalTaxes() 0 5 1
A setCustomerRegName() 0 3 1
A getRawData() 0 2 1
A getCustomerRegName() 0 2 1
A getCurrencyCode() 0 2 1
A getDocumentSeries() 0 2 1
A getPurchaseOrder() 0 2 1
A applyAllowancesAndCharges() 0 2 1
A setIssueDate() 0 3 1
A getIVAP() 0 2 1
A getTotalItems() 0 2 1
A getTotalExemptedOperations() 0 3 1
A getDocumentName() 0 2 1
A getAllowancesAndCharges() 0 2 1
A getDocumentType() 0 2 1
A getIssueDate() 0 2 1
A getCustomerDocNumber() 0 2 1

How to fix   Complexity   

Complex Class

Complex classes like DataMap 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 DataMap, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * MÓDULO DE EMISIÓN ELECTRÓNICA F72X
5
 * UBL 2.1
6
 * Version 1.1
7
 * 
8
 * Copyright 2018, Jaime Cruz
9
 */
10
11
namespace F72X\Sunat;
12
13
use DateTime;
14
use F72X\Company;
15
use F72X\Sunat\Catalogo;
16
/**
17
 * DataMap
18
 * 
19
 * Esta clase es una representación interna de una factura o boleta, la cual se
20
 * encarga de aplicar toda la logica de negocio en cuanto a cálculos de tributos
21
 * y totales
22
 * 
23
 */
24
class DataMap {
25
26
    private $_rawData;
27
    private $documentType;
28
    private $currencyCode;
29
    private $invoiceId;
30
    private $documentName;
31
    private $documentSeries;
32
    private $documentNumber;
33
34
    /** @var DateTime */
35
    private $issueDate;
36
37
    /** @var DateTime */
38
    protected $DueDate;
39
    private $operationType;
40
    private $customerDocType;
41
    private $customerDocNumber;
42
    private $customerRegName;
43
    private $customerAddress;
44
    private $purchaseOrder;
45
46
    /** @var InvoiceItems */
47
    private $_items;
48
    private $_rawItems;
49
    private $allowancesAndCharges = [];
50
51
    /** NOTES FIELDS */
52
    private $noteType;
53
    private $noteDescription;
54
    private $noteAffectedDocType;
55
    private $noteAffectedDocId;
56
    /**
57
     * 
58
     * @param array $data
59
     * @param string $type 01|03|07|08
60
     */
61
    public function __construct(array $data, $type) {
62
        // Items
63
        $items = new InvoiceItems();
64
        $items->populate($data['items'], $data['currencyCode']);
65
66
        $this->_rawData  = $data;
67
        $this->_rawItems = $data['items'];
68
        $this->setDefaults($data);
69
        $this->currencyCode         = $data['currencyCode'];
70
        $this->documentType         = $type;
71
        $this->documentSeries       = $data['documentSeries'];
72
        $this->documentNumber       = str_pad($data['documentNumber'], 8, '0', STR_PAD_LEFT);
73
        $this->documentName         = Catalogo::getDocumentName($type);
74
        $this->invoiceId            = $this->documentSeries . '-' . $this->documentNumber;
75
        $this->issueDate            = new DateTime($data['issueDate']);
76
        $this->customerDocType      = $data['customerDocType'];
77
        $this->customerDocNumber    = $data['customerDocNumber'];
78
        $this->customerRegName      = mb_strtoupper($data['customerRegName']);
79
        $this->customerAddress      = mb_strtoupper($data['customerAddress']);
80
        $this->_items               = $items;
81
        $this->allowancesAndCharges = $data['allowancesCharges'];
82
        $this->setSpecificFields($data, $type);
83
    }
84
85
    private function setSpecificFields(array $data, $type) {
86
        if (in_array($type, [Catalogo::DOCTYPE_FACTURA, Catalogo::DOCTYPE_BOLETA])) {
87
            $this->operationType        = $data['operationType'];
88
            $this->purchaseOrder        = $data['purchaseOrder'];
89
        }else{
90
            
91
            $this->noteType            = $data['type'];
92
            $this->noteDescription     = $data['description'];
93
            $this->noteAffectedDocType = $data['affectedDocType'];
94
            $this->noteAffectedDocId   = $data['affectedDocId'];
95
        }
96
    }
97
98
    private function setDefaults(array &$data) {
99
        $data['allowancesCharges'] = isset($data['allowancesCharges']) ? $data['allowancesCharges'] : [];
100
        $data['purchaseOrder'] = isset($data['purchaseOrder']) ? $data['purchaseOrder'] : null;
101
    }
102
    public function getNoteType() {
103
        return $this->noteType;
104
    }
105
106
    public function getNoteDescription() {
107
        return $this->noteDescription;
108
    }
109
110
    public function getNoteAffectedDocType() {
111
        return $this->noteAffectedDocType;
112
    }
113
114
    public function getNoteAffectedDocId() {
115
        return $this->noteAffectedDocId;
116
    }
117
118
    public function getInvoiceId() {
119
        return $this->invoiceId;
120
    }
121
122
    public function getRawData() {
123
        return $this->_rawData;
124
    }
125
126
    /**
127
     * Boleta o Factura @CAT1
128
     * @return string
129
     */
130
    public function getDocumentType() {
131
        return $this->documentType;
132
    }
133
134
    public function getCurrencyCode() {
135
        return $this->currencyCode;
136
    }
137
138
    public function getDocumentName() {
139
        return $this->documentName;
140
    }
141
142
    public function getDocumentSeries() {
143
        return $this->documentSeries;
144
    }
145
146
    public function setDocumentSeries($documentSeries) {
147
        $this->documentSeries = $documentSeries;
148
        return $this;
149
    }
150
151
    public function getDocumentNumber() {
152
        return $this->documentNumber;
153
    }
154
155
    public function setDocumentNumber($documentNumber) {
156
        $this->documentNumber = $documentNumber;
157
        return $this;
158
    }
159
160
    public function getIssueDate() {
161
        return $this->issueDate;
162
    }
163
164
    public function setIssueDate(DateTime $IssueDate) {
165
        $this->issueDate = $IssueDate;
166
        return $this;
167
    }
168
169
    public function getDueDate() {
170
        return $this->DueDate;
171
    }
172
173
    public function setDueDate(DateTime $DueDate) {
174
        $this->DueDate = $DueDate;
175
        return $this;
176
    }
177
178
    public function getOperationType() {
179
        return $this->operationType;
180
    }
181
182
    public function setOperationType($operationType) {
183
        $this->operationType = $operationType;
184
        return $this;
185
    }
186
187
    public function getCustomerDocType() {
188
        return $this->customerDocType;
189
    }
190
191
    public function setCustomerDocType($customerDocType) {
192
        $this->customerDocType = $customerDocType;
193
        return $this;
194
    }
195
196
    public function getCustomerDocNumber() {
197
        return $this->customerDocNumber;
198
    }
199
200
    public function setCustomerDocNumber($customerDocNumber) {
201
        $this->customerDocNumber = $customerDocNumber;
202
        return $this;
203
    }
204
205
    public function getCustomerRegName() {
206
        return $this->customerRegName;
207
    }
208
209
    public function setCustomerRegName($customerRegName) {
210
        $this->customerRegName = $customerRegName;
211
        return $this;
212
    }
213
    public function getCustomerAddress() {
214
        return $this->customerAddress;
215
    }
216
217
    public function setCustomerAddress($customerAddress) {
218
        $this->customerAddress = $customerAddress;
219
        return $this;
220
    }
221
222
    public function getPurchaseOrder() {
223
        return $this->purchaseOrder;
224
    }
225
226
    public function setPurchaseOrder($purchaseOrder) {
227
        $this->purchaseOrder = $purchaseOrder;
228
        return $this;
229
    }
230
231
    /**
232
     * 
233
     * @return InvoiceItems
234
     */
235
    public function getItems() {
236
        return $this->_items;
237
    }
238
239
    /**
240
     * Numero de items del documento
241
     * @return int
242
     */
243
    public function getTotalItems() {
244
        return $this->_items->getCount();
245
    }
246
247
    public function getRawItems() {
248
        return $this->_rawItems;
249
    }
250
251
    public function getAllowancesAndCharges() {
252
        return $this->allowancesAndCharges;
253
    }
254
255
    public function setAllowancesAndCharges($allowancesAndCharges) {
256
        $this->allowancesAndCharges = $allowancesAndCharges;
257
        return $this;
258
    }
259
260
    /**
261
     * Base imponible
262
     * 
263
     * Formula = SUM(BASE_IMPONIBLE_X_ITEM) - DESCUENTOS_GLOBALES + CARGOS_GLOBALES
264
     * 
265
     * @return float
266
     */
267
    public function getTaxableAmount() {
268
        $totalItems = $this->_items->getTotalTaxableOperations();
269
        return $this->applyAllowancesAndCharges($totalItems);
270
    }
271
272
    /**
273
     * Monto con impuestos
274
     * 
275
     * Formula = BASE_IMPONIBLE + IGV
276
     * 
277
     * @return float
278
     */
279
    public function getTaxedAmount() {
280
        $totalTaxableAmount = $this->getTaxableAmount();
281
        $totalIgv = $this->getIGV();
282
        return $totalTaxableAmount + $totalIgv;
283
    }
284
285
    /**
286
     * Total operaciones gravadas
287
     * @return float
288
     */
289
    public function getTotalTaxableOperations() {
290
        return $this->getTaxableAmount();
291
    }
292
293
    /**
294
     * Total operaciones gratuitas
295
     * @return float
296
     */
297
    public function getTotalFreeOperations() {
298
        return $this->_items->getTotalFreeOperations();
299
    }
300
301
    /**
302
     * Total operationes exoneradas
303
     * 
304
     * Formula = SUM(EXEMPTED_OPERATIONS_X_ITEM) - DESCUENTOS_GLOBALES + CARGOS_GLOBALES
305
     * 
306
     * @return float
307
     */
308
    public function getTotalExemptedOperations() {
309
        $totalItems = $this->_items->getTotalExemptedOperations();
310
        return $this->applyAllowancesAndCharges($totalItems);
311
    }
312
313
    /**
314
     * Total operaciones inafectas
315
     * @return float
316
     */
317
    public function getTotalUnaffectedOperations() {
318
        $totalItems = $this->_items->getTotalUnaffectedOperations();
319
        return $this->applyAllowancesAndCharges($totalItems);
320
    }
321
322
    /**
323
     * Valor de venta
324
     * 
325
     * Valor total de la factura sin considerar descuentos impuestos u otros tributos
326
     * @return float
327
     */
328
    public function getBillableValue() {
329
        return $this->_items->getTotalBillableValue();
330
    }
331
332
    /**
333
     * Total descuentos
334
     * 
335
     * Formula: SUM(DESCUENTOS_X_ITEM) + DESCUENTOS_GLOBALES
336
     * @return float
337
     */
338
    public function getTotalAllowances() {
339
        $totalItems = $this->_items->getTotalAllowances();
340
        $totalTaxableAmountItems = $this->_items->getTotalTaxableAmount();
341
        $globalAllowancesAmount = Operations::getTotalAllowances($totalTaxableAmountItems, $this->allowancesAndCharges);
342
        return $totalItems + $globalAllowancesAmount;
343
    }
344
345
    /**
346
     * Total a pagar
347
     * 
348
     * El importe que el usuario está obligado a pagar
349
     * 
350
     * Formula = OPERACIONES_GRAVADAS + IGV + OPERACIONES_EXONERADAS + OPERACIONES_INAFECTAS
351
     * 
352
     * @return float
353
     */
354
    public function getPayableAmount() {
355
        // Totals
356
        $totalTaxableOperations = $this->getTotalTaxableOperations();
357
        $totalIGV = $this->getIGV();
358
        $totalExemptedOperations = $this->getTotalExemptedOperations();
359
        return $totalTaxableOperations + $totalIGV + $totalExemptedOperations;
360
    }
361
362
    /**
363
     * 
364
     * Total impuestos
365
     * 
366
     * Fórmula: IGV + ISC + IVAP
367
     * 
368
     * @return float
369
     */
370
    public function getTotalTaxes() {
371
        $IGV = $this->getIGV();
372
        $ISC = $this->getISC();
373
        $IVAP = $this->getIVAP();
374
        return $IGV + $ISC + $IVAP;
375
    }
376
377
    /**
378
     * IGV
379
     * @return float
380
     */
381
    public function getIGV() {
382
        $baseAmount = $this->getTaxableAmount();
383
        return Operations::calcIGV($baseAmount);
384
    }
385
386
    /**
387
     * ISC
388
     * @IMP
389
     * @return float
390
     */
391
    public function getISC() {
392
        return Operations::calcISC();
393
    }
394
395
    /**
396
     * IVAP
397
     * @IMP
398
     * @return float
399
     */
400
    public function getIVAP() {
401
        return Operations::calcIVAP();
402
    }
403
404
    /**
405
     * 
406
     * @param float $amount
407
     * @return float
408
     */
409
    private function applyAllowancesAndCharges($amount) {
410
        return Operations::applyAllowancesAndCharges($amount, $this->allowancesAndCharges);
411
    }
412
    public function getBillName() {
413
        return Company::getRUC() . '-' . $this->documentType . '-' . $this->invoiceId;
414
    }
415
}
416