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

BillMixin   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 312
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 192
dl 0
loc 312
rs 10
c 0
b 0
f 0
wmc 27

12 Methods

Rating   Name   Duplication   Size   Complexity  
A addInvoiceOrderReference() 0 8 2
B addDocumentItem() 0 100 3
A addDocumentLine() 0 11 4
A addInvoiceLegalMonetaryTotal() 0 16 1
A addInvoiceAccountingCustomerParty() 0 27 1
A setDocumentLineQuantity() 0 11 4
B addDocumentTaxes() 0 36 6
A addInvoiceAccountingSupplierParty() 0 30 1
A addDocumentItems() 0 5 2
A getBillName() 0 2 1
A getItems() 0 2 1
A getDataMap() 0 2 1
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\Document;
12
13
use F72X\Company;
14
use F72X\Sunat\DataMap;
15
use F72X\Sunat\InvoiceItems;
16
use F72X\Sunat\Catalogo;
17
use F72X\Sunat\SunatVars;
18
use F72X\Tools\UblHelper;
19
use F72X\UblComponent\OrderReference;
20
use F72X\UblComponent\Party;
21
use F72X\UblComponent\PartyIdentification;
22
use F72X\UblComponent\PartyName;
23
use F72X\UblComponent\AccountingSupplierParty;
24
use F72X\UblComponent\AccountingCustomerParty;
25
use F72X\UblComponent\PartyLegalEntity;
26
use F72X\UblComponent\TaxTotal;
27
use F72X\UblComponent\TaxSubTotal;
28
use F72X\UblComponent\TaxCategory;
29
use F72X\UblComponent\TaxScheme;
30
use F72X\UblComponent\LegalMonetaryTotal;
31
use F72X\UblComponent\InvoiceLine;
32
use F72X\UblComponent\CreditNoteLine;
33
use F72X\UblComponent\DebitNoteLine;
34
use F72X\UblComponent\PricingReference;
35
use F72X\UblComponent\AlternativeConditionPrice;
36
use F72X\UblComponent\Item;
37
use F72X\UblComponent\SellersItemIdentification;
38
use F72X\UblComponent\CommodityClassification;
39
use F72X\UblComponent\Price;
40
41
trait BillMixin {
42
43
    
44
45
    /** @var DataMap */
46
    private $dataMap;
47
48
    public function getDataMap() {
49
        return $this->dataMap;
50
    }
51
52
    /**
53
     * 
54
     * @return InvoiceItems
55
     */
56
    public function getItems() {
57
        return $this->dataMap->getItems();
58
    }
59
60
    /**
61
     * 
62
     * @param string $lineType InvoiceLine|CreditNoteLine|DebitNoteLine
63
     */
64
    private function addDocumentItems($lineType) {
65
        $ln = $this->dataMap->getTotalItems();
66
        // Loop
67
        for ($i = 0; $i < $ln; $i++) {
68
            $this->addDocumentItem($i, $lineType);
69
        }
70
    }
71
72
    private function addInvoiceOrderReference() {
73
        $orderNumer = $this->dataMap->getPurchaseOrder();
74
        if ($orderNumer) {
75
            // Xml Node
76
            $orderRef = new OrderReference();
77
            $orderRef->setID($orderNumer);
78
            // Añadir al documento
79
            $this->setOrderReference($orderRef);
0 ignored issues
show
Bug introduced by
It seems like setOrderReference() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

79
            $this->/** @scrutinizer ignore-call */ 
80
                   setOrderReference($orderRef);
Loading history...
80
        }
81
    }
82
83
    private function addDocumentTaxes() {
84
        $Invoice                   = $this->dataMap;
85
        $currencyID                = $Invoice->getCurrencyCode();              // Tipo de moneda
86
        $totalTaxableOperations    = $Invoice->getTotalTaxableOperations();    // Total operaciones gravadas
87
        $totalTaxes                = $Invoice->getTotalTaxes();                // Total operaciones gravadas
88
        $Igv                       = $Invoice->getIGV();                       // Total IGV
89
        $totalExemptedOperations   = $Invoice->getTotalExemptedOperations();   // Total operaciones exoneradas
90
        $totalUnaffectedOperations = $Invoice->getTotalUnaffectedOperations(); // Total operaciones inafectas
91
        $totalFreeOpertions        = $Invoice->getTotalFreeOperations();       // Total operaciones gratuitas
92
93
        // XML nodes
94
        $TaxTotal = new TaxTotal();
95
96
        // Operaciones gravadas
97
        if ($Igv) {
98
            UblHelper::addTaxSubtotal($TaxTotal, $currencyID, $Igv, $totalTaxableOperations, Catalogo::CAT5_IGV);
99
        }
100
        // Total operaciones exoneradas
101
        if ($totalExemptedOperations) {
102
            UblHelper::addTaxSubtotal($TaxTotal, $currencyID, 0, $totalExemptedOperations,   Catalogo::CAT5_EXO);
103
        }
104
        // Total operaciones inafectas
105
        if ($totalUnaffectedOperations) {
106
            UblHelper::addTaxSubtotal($TaxTotal, $currencyID, 0, $totalUnaffectedOperations, Catalogo::CAT5_INA);
107
        }
108
        // Total operaciones gratuitas solo aplica a FACTURA
109
        if ($totalFreeOpertions && $Invoice->getDocumentType() === Catalogo::DOCTYPE_FACTURA) {
110
            UblHelper::addTaxSubtotal($TaxTotal, $currencyID, 0, $totalFreeOpertions,        Catalogo::CAT5_GRA);
111
        }
112
113
        // Total impuestos
114
        $TaxTotal
115
                ->setCurrencyID($currencyID)
116
                ->setTaxAmount($totalTaxes);
117
        // Anadir al documento
118
        $this->setTaxTotal($TaxTotal);
0 ignored issues
show
Bug introduced by
It seems like setTaxTotal() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
        $this->/** @scrutinizer ignore-call */ 
119
               setTaxTotal($TaxTotal);
Loading history...
119
    }
120
121
    /**
122
     * 
123
     * @param int $itemIndex Index del item
124
     * @param string $lineType InvoiceLine|CreditNoteLine|DebitNoteLine
125
     */
126
    
127
    private function addDocumentItem($itemIndex, $lineType) {
128
        $docLineClassName = "\F72X\UblComponent\\$lineType";
129
        // XML Nodes
130
        $DocumentLine     = new $docLineClassName();
131
        $PricingReference = new PricingReference();
132
        $TaxTotal         = new TaxTotal();
133
        $TaxSubTotal      = new TaxSubTotal();
134
        $TaxCategory      = new TaxCategory();
135
        $TaxCategory
136
                ->setElementAttributes('ID', [
137
                    'schemeID'         => 'UN/ECE 5305',
138
                    'schemeName'       => 'Tax Category Identifier',
139
                    'schemeAgencyName' => 'United Nations Economic Commission for Europe'])
140
                ->setElementAttributes('TaxExemptionReasonCode', [
141
                    'listAgencyName'   => 'PE:SUNAT',
142
                    'listName'         => 'SUNAT:Codigo de Tipo de Afectación del IGV',
143
                    'listURI'          => 'urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo07']);
144
145
        $TaxScheme = new TaxScheme();
146
        $TaxScheme
147
                ->setElementAttributes('ID', [
148
                    'schemeID'         => 'UN/ECE 5153',
149
                    'schemeName'       => 'Tax Scheme Identifier',
150
                    'schemeAgencyName' => 'United Nations Economic Commission for Europe']);
151
152
        $AlternativeConditionPrice  = new AlternativeConditionPrice();
153
        $Item                       = new Item();
154
        $SellersItemIdentification  = new SellersItemIdentification();
155
        $CommodityClassification    = new CommodityClassification();
156
        $Price                      = new Price();
157
        // Detail Operation Matrix
158
        $Items = $this->dataMap->getItems();
159
        // Vars
160
        $productCode        = $Items->getProductCode($itemIndex);
161
        $sunatProductCode   = $Items->getUNPSC($itemIndex);
162
        $unitCode           = $Items->getUnitCode($itemIndex);
163
        $quantity           = $Items->getQunatity($itemIndex);
164
        $description        = $Items->getDescription($itemIndex);
165
        $currencyCode       = $Items->getCurrencyCode($itemIndex);
166
        $unitBillableValue  = $Items->getUnitBillableValue($itemIndex);
167
        $priceTypeCode      = $Items->getPriceTypeCode($itemIndex);
168
        $taxTypeCode        = $Items->getTaxTypeCode($itemIndex);
169
        $igvAffectationType = $Items->getIgvAffectationType($itemIndex);
170
171
        $itemValue          = $Items->getItemValue($itemIndex);
172
        $ac                 = $Items->getAllowancesAndCharges($itemIndex);
173
        $itemTaxableAmount  = $Items->getTaxableAmount($itemIndex);
174
        $itemTaxAmount      = $Items->getIgv($itemIndex);
175
        $unitPrice          = $Items->getUnitTaxedValue($itemIndex);
176
177
        // Catálogo 5 Ipuesto aplicable
178
        $cat5Item = Catalogo::getCatItem(5, $taxTypeCode);
179
180
        // Descuentos y cargos
181
        UblHelper::addAllowancesCharges($DocumentLine, $ac, $itemValue, $currencyCode);
182
183
        // Config Item
184
        $Item->setDescription($description); // Descripción
185
        // Código de producto
186
        if ($productCode) {
187
            $Item->setSellersItemIdentification($SellersItemIdentification->setID($productCode));
188
        }
189
        // Código de producto SUNAT
190
        if ($sunatProductCode) {
191
            $Item->setCommodityClassification($CommodityClassification->setItemClassificationCode($sunatProductCode));
192
        }
193
        $DocumentLine
194
                ->setCurrencyID($currencyCode)                    // Tipo de moneda
195
                ->setID($itemIndex + 1)                         // Número de orden
196
                ->setUnitCode($unitCode)                        // Codigo de unidad de medida
197
                ->setLineExtensionAmount($itemTaxableAmount)    // Valor de venta del ítem, sin impuestos
198
                ->setPricingReference($PricingReference
199
                        ->setAlternativeConditionPrice($AlternativeConditionPrice
200
                                ->setCurrencyID($currencyCode)            // Tipo de moneda
201
                                ->setPriceAmount($unitPrice)            // Precio de venta unitario
202
                                ->setPriceTypeCode($priceTypeCode)))    // Price
203
                ->setTaxTotal($TaxTotal
204
                        ->setCurrencyID($currencyCode)
205
                        ->setTaxAmount($itemTaxAmount)
206
                        ->addTaxSubTotal($TaxSubTotal
207
                                ->setCurrencyID($currencyCode)            // Tipo de moneda
208
                                ->setTaxableAmount($itemTaxableAmount)  // Valor de venta del item sin impuestos
209
                                ->setTaxAmount($itemTaxAmount)          // IGV
210
                                ->setTaxCategory($TaxCategory
211
                                        ->setID($cat5Item['categoria'])                     // Codigo de categoria de immpuestos @CAT5
212
                                        ->setPercent(SunatVars::IGV_PERCENT)                // Porcentaje de IGV (18.00)
213
                                        ->setTaxExemptionReasonCode($igvAffectationType)    // Código de afectación del IGV
214
                                        ->setTaxScheme($TaxScheme
215
                                                ->setID($taxTypeCode)                       // Codigo de categoria de impuesto
216
                                                ->setName($cat5Item['name'])
217
                                                ->setTaxTypeCode($cat5Item['UN_ECE_5153'])))))
218
                ->setItem($Item)
219
                ->setPrice($Price
220
                        ->setCurrencyID($currencyCode)    // Tipo de moneda
221
                        ->setPriceAmount($unitBillableValue)    // Precio unitario del item
222
        );
223
        // Set Quantity
224
        $this->setDocumentLineQuantity($DocumentLine, $lineType, $quantity);
225
        // Añade item
226
        $this->addDocumentLine($DocumentLine, $lineType);
227
    }
228
229
    /**
230
     * 
231
     * @param InvoiceLine|CreditNoteLine|DebitNoteLine $DocumentLine
232
     * @param string $lineType InvoiceLine|CreditNoteLine|DebitNoteLine
233
     * @param int $quantity
234
     */
235
    private function addDocumentLine($DocumentLine, $lineType) {
236
        switch ($lineType) {
237
            case 'InvoiceLine':
238
                $this->addInvoiceLine($DocumentLine);
0 ignored issues
show
Bug introduced by
It seems like addInvoiceLine() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

238
                $this->/** @scrutinizer ignore-call */ 
239
                       addInvoiceLine($DocumentLine);
Loading history...
239
                break;
240
            case 'CreditNoteLine' :
241
                $this->addCreditNoteLine($DocumentLine);
0 ignored issues
show
Bug introduced by
It seems like addCreditNoteLine() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
                $this->/** @scrutinizer ignore-call */ 
242
                       addCreditNoteLine($DocumentLine);
Loading history...
242
                break;
243
            case 'DebitNoteLine' :
244
                $this->addDebitNoteLine($DocumentLine);
0 ignored issues
show
Bug introduced by
It seems like addDebitNoteLine() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

244
                $this->/** @scrutinizer ignore-call */ 
245
                       addDebitNoteLine($DocumentLine);
Loading history...
245
                break;
246
        }
247
    }
248
    /**
249
     * 
250
     * @param InvoiceLine|CreditNoteLine|DebitNoteLine $DocumentLine
251
     * @param string $lineType InvoiceLine|CreditNoteLine|DebitNoteLine
252
     * @param int $quantity
253
     */
254
    private function setDocumentLineQuantity($DocumentLine, $lineType, $quantity) {
255
        switch ($lineType) {
256
            case 'InvoiceLine':
257
                $DocumentLine->setInvoicedQuantity($quantity);
0 ignored issues
show
Bug introduced by
The method setInvoicedQuantity() does not exist on F72X\UblComponent\CreditNoteLine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

257
                $DocumentLine->/** @scrutinizer ignore-call */ 
258
                               setInvoicedQuantity($quantity);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method setInvoicedQuantity() does not exist on F72X\UblComponent\DebitNoteLine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

257
                $DocumentLine->/** @scrutinizer ignore-call */ 
258
                               setInvoicedQuantity($quantity);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
258
                break;
259
            case 'CreditNoteLine' :
260
                $DocumentLine->setCreditedQuantity($quantity);
0 ignored issues
show
Bug introduced by
The method setCreditedQuantity() does not exist on F72X\UblComponent\DebitNoteLine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
                $DocumentLine->/** @scrutinizer ignore-call */ 
261
                               setCreditedQuantity($quantity);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method setCreditedQuantity() does not exist on F72X\UblComponent\InvoiceLine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
                $DocumentLine->/** @scrutinizer ignore-call */ 
261
                               setCreditedQuantity($quantity);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
261
                break;
262
            case 'DebitNoteLine' :
263
                $DocumentLine->setDebitedQuantity($quantity);
0 ignored issues
show
Bug introduced by
The method setDebitedQuantity() does not exist on F72X\UblComponent\CreditNoteLine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

263
                $DocumentLine->/** @scrutinizer ignore-call */ 
264
                               setDebitedQuantity($quantity);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method setDebitedQuantity() does not exist on F72X\UblComponent\InvoiceLine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

263
                $DocumentLine->/** @scrutinizer ignore-call */ 
264
                               setDebitedQuantity($quantity);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
264
                break;
265
        }
266
    }
267
268
    private function addInvoiceLegalMonetaryTotal() {
269
        $Invoice            = $this->dataMap;
270
        $currencyID         = $this->getDocumentCurrencyCode(); // Tipo de moneda
0 ignored issues
show
Bug introduced by
It seems like getDocumentCurrencyCode() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

270
        /** @scrutinizer ignore-call */ 
271
        $currencyID         = $this->getDocumentCurrencyCode(); // Tipo de moneda
Loading history...
271
        $totalAllowances    = $Invoice->getTotalAllowances();   // Total descuentos
272
        $payableAmount      = $Invoice->getPayableAmount();     // Total a pagar
273
        $billableAmount     = $Invoice->getBillableValue();
274
        // LegalMonetaryTotal
275
        $LegalMonetaryTotal = new LegalMonetaryTotal();
276
        $LegalMonetaryTotal
277
                ->setCurrencyID($currencyID)
278
                ->setLineExtensionAmount($billableAmount)
279
                ->setTaxInclusiveAmount($payableAmount)
280
                ->setAllowanceTotalAmount($totalAllowances)
281
                ->setPayableAmount($payableAmount);
282
283
        $this->setLegalMonetaryTotal($LegalMonetaryTotal);
0 ignored issues
show
Bug introduced by
It seems like setLegalMonetaryTotal() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

283
        $this->/** @scrutinizer ignore-call */ 
284
               setLegalMonetaryTotal($LegalMonetaryTotal);
Loading history...
284
    }
285
286
    private function addInvoiceAccountingSupplierParty() {
287
        // Info
288
        $partyName  = Company::getBusinessName();
289
        $regName    = Company::getCompanyName();
290
        $docNumber  = Company::getRUC();
291
        $docType    = Catalogo::IDENTIFICATION_DOC_RUC;
292
293
        // XML nodes
294
        $AccountingSupplierParty    = new AccountingSupplierParty();
295
        $Party                      = new Party();
296
        $PartyIdentification        = new PartyIdentification();
297
        $PartyIdentification
298
                ->setElementAttributes('ID', [
299
                    'schemeAgencyName'  => 'PE:SUNAT',
300
                    'schemeID'          => $docType,
301
                    'schemeName'        => 'Documento de Identidad',
302
                    'schemeURI'         => 'urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06']);
303
        $PartyName                  = new PartyName();
304
        $PartyLegalEntity           = new PartyLegalEntity();
305
306
        $AccountingSupplierParty
307
                ->setParty($Party
308
                        ->setPartyIdentification($PartyIdentification
309
                                ->setID($docNumber))
310
                        ->setPartyName($PartyName
311
                                ->setName($partyName))
312
                        ->setPartyLegalEntity($PartyLegalEntity
313
                                ->setRegistrationName($regName)));
314
        // Add to Document
315
        $this->setAccountingSupplierParty($AccountingSupplierParty);
0 ignored issues
show
Bug introduced by
It seems like setAccountingSupplierParty() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

315
        $this->/** @scrutinizer ignore-call */ 
316
               setAccountingSupplierParty($AccountingSupplierParty);
Loading history...
316
    }
317
318
    private function addInvoiceAccountingCustomerParty() {
319
        $Invoice   = $this->dataMap;
320
        // Info
321
        $regName   = $Invoice->getCustomerRegName();
322
        $docNumber = $Invoice->getCustomerDocNumber();
323
        $docType   = $Invoice->getCustomerDocType();
324
325
        // XML nodes
326
        $AccountingCustomerParty    = new AccountingCustomerParty();
327
        $Party                      = new Party();
328
        $PartyIdentification        = new PartyIdentification();
329
        $PartyLegalEntity           = new PartyLegalEntity();
330
        $PartyIdentification
331
                ->setElementAttributes('ID', [
332
                    'schemeAgencyName'  => 'PE:SUNAT',
333
                    'schemeID'          => $docType,
334
                    'schemeName'        => 'Documento de Identidad',
335
                    'schemeURI'         => 'urn:pe:gob:sunat:cpe:see:gem:catalogos:catalogo06']);
336
337
        $AccountingCustomerParty
338
                ->setParty($Party
339
                        ->setPartyIdentification($PartyIdentification
340
                                ->setID($docNumber))
341
                        ->setPartyLegalEntity($PartyLegalEntity
342
                                ->setRegistrationName($regName)));
343
        // Add to Document
344
        $this->setAccountingCustomerParty($AccountingCustomerParty);
0 ignored issues
show
Bug introduced by
It seems like setAccountingCustomerParty() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

344
        $this->/** @scrutinizer ignore-call */ 
345
               setAccountingCustomerParty($AccountingCustomerParty);
Loading history...
345
    }
346
347
    /**
348
     *    
349
     * @return string Nombre del comprobante de acuerdo con las especificaciones de la SUNAT
350
     */
351
    public function getBillName() {
352
        return $this->dataMap->getBillName();
353
    }
354
355
}
356