1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* LibreDTE |
5
|
|
|
* Copyright (C) SASCO SpA (https://sasco.cl) |
6
|
|
|
* |
7
|
|
|
* Este programa es software libre: usted puede redistribuirlo y/o |
8
|
|
|
* modificarlo bajo los términos de la Licencia Pública General Affero de GNU |
9
|
|
|
* publicada por la Fundación para el Software Libre, ya sea la versión |
10
|
|
|
* 3 de la Licencia, o (a su elección) cualquier versión posterior de la |
11
|
|
|
* misma. |
12
|
|
|
* |
13
|
|
|
* Este programa se distribuye con la esperanza de que sea útil, pero |
14
|
|
|
* SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita |
15
|
|
|
* MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO. |
16
|
|
|
* Consulte los detalles de la Licencia Pública General Affero de GNU para |
17
|
|
|
* obtener una información más detallada. |
18
|
|
|
* |
19
|
|
|
* Debería haber recibido una copia de la Licencia Pública General Affero de GNU |
20
|
|
|
* junto a este programa. |
21
|
|
|
* En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>. |
22
|
|
|
*/ |
23
|
|
|
|
24
|
|
|
namespace sasco\LibreDTE\Sii\PDF; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Clase para generar el PDF de un documento tributario electrónico (DTE) |
28
|
|
|
* chileno. |
29
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
30
|
|
|
* @version 2018-04-13 |
31
|
|
|
*/ |
32
|
|
|
class Dte extends \sasco\LibreDTE\PDF |
33
|
|
|
{ |
34
|
|
|
|
35
|
|
|
protected $dte; ///< Tipo de DTE que se está generando |
36
|
|
|
protected $logo; ///< Datos del logo que se ubicará en el PDF (ruta, datos y/o posición) |
37
|
|
|
protected $resolucion; ///< Arreglo con los datos de la resolución (índices: NroResol y FchResol) |
38
|
|
|
protected $cedible = false; ///< Por defecto DTEs no son cedibles |
39
|
|
|
protected $papelContinuo = false; ///< Indica si se usa papel continuo o no |
40
|
|
|
protected $sinAcuseRecibo = [39, 41, 56, 61, 110, 111, 112]; ///< Boletas, notas de crédito y notas de débito no tienen acuse de recibo |
41
|
|
|
protected $web_verificacion = 'www.sii.cl'; ///< Página web para verificar el documento |
42
|
|
|
protected $ecl = 5; ///< error correction level para PHP >= 7.0.0 |
43
|
|
|
protected $papel_continuo_alto = 5000; ///< Alto exageradamente grande para autocálculo de alto en papel continuo |
44
|
|
|
protected $timbre_pie = true; ///< Indica si el timbre va al pie o no (va pegado al detalle) |
45
|
|
|
|
46
|
|
|
private $tipos = [ |
47
|
|
|
// códigos oficiales SII |
48
|
|
|
29 => 'FACTURA DE INICIO', |
49
|
|
|
30 => 'FACTURA', |
50
|
|
|
32 => 'FACTURA DE VENTA BIENES Y SERVICIOS NO AFECTOS O EXENTOS DE IVA', |
51
|
|
|
33 => 'FACTURA ELECTRÓNICA', |
52
|
|
|
34 => 'FACTURA NO AFECTA O EXENTA ELECTRÓNICA', |
53
|
|
|
35 => 'BOLETA', |
54
|
|
|
38 => 'BOLETA EXENTA', |
55
|
|
|
39 => 'BOLETA ELECTRÓNICA', |
56
|
|
|
40 => 'LIQUIDACION FACTURA', |
57
|
|
|
41 => 'BOLETA NO AFECTA O EXENTA ELECTRÓNICA', |
58
|
|
|
43 => 'LIQUIDACIÓN FACTURA ELECTRÓNICA', |
59
|
|
|
45 => 'FACTURA DE COMPRA', |
60
|
|
|
46 => 'FACTURA DE COMPRA ELECTRÓNICA', |
61
|
|
|
48 => 'COMPROBANTE DE PAGO ELECTRÓNICO', |
62
|
|
|
50 => 'GUÍA DE DESPACHO', |
63
|
|
|
52 => 'GUÍA DE DESPACHO ELECTRÓNICA', |
64
|
|
|
55 => 'NOTA DE DÉBITO', |
65
|
|
|
56 => 'NOTA DE DÉBITO ELECTRÓNICA', |
66
|
|
|
60 => 'NOTA DE CRÉDITO', |
67
|
|
|
61 => 'NOTA DE CRÉDITO ELECTRÓNICA', |
68
|
|
|
101 => 'FACTURA DE EXPORTACIÓN', |
69
|
|
|
102 => 'FACTURA DE VENTA EXENTA A ZONA FRANCA PRIMARIA', |
70
|
|
|
103 => 'LIQUIDACIÓN', |
71
|
|
|
104 => 'NOTA DE DÉBITO DE EXPORTACIÓN', |
72
|
|
|
105 => 'BOLETA LIQUIDACIÓN', |
73
|
|
|
106 => 'NOTA DE CRÉDITO DE EXPORTACIÓN', |
74
|
|
|
108 => 'SOLICITUD REGISTRO DE FACTURA (SRF)', |
75
|
|
|
109 => 'FACTURA TURISTA', |
76
|
|
|
110 => 'FACTURA DE EXPORTACIÓN ELECTRÓNICA', |
77
|
|
|
111 => 'NOTA DE DÉBITO DE EXPORTACIÓN ELECTRÓNICA', |
78
|
|
|
112 => 'NOTA DE CRÉDITO DE EXPORTACIÓN ELECTRÓNICA', |
79
|
|
|
801 => 'ORDEN DE COMPRA', |
80
|
|
|
802 => 'NOTA DE PEDIDO', |
81
|
|
|
803 => 'CONTRATO', |
82
|
|
|
804 => 'RESOLUCIÓN', |
83
|
|
|
805 => 'PROCEDO CHILECOMPRA', |
84
|
|
|
806 => 'FICHA CHILECOMPRA', |
85
|
|
|
807 => 'DUS', |
86
|
|
|
808 => 'B/L (CONOCIMIENTO DE EMBARQUE)', |
87
|
|
|
809 => 'AWB', |
88
|
|
|
810 => 'MIC (MANIFIESTO INTERNACIONAL)', |
89
|
|
|
811 => 'CARTA DE PORTE', |
90
|
|
|
812 => 'RESOLUCION SNA', |
91
|
|
|
813 => 'PASAPORTE', |
92
|
|
|
814 => 'CERTIFICADO DE DEPÓSITO BOLSA PROD. CHILE', |
93
|
|
|
815 => 'VALE DE PRENDA BOLSA PROD. CHILE', |
94
|
|
|
901 => 'FACTURA DE VENTAS A EMPRESAS DEL TERRITORIO PREFERENCIAL', |
95
|
|
|
902 => 'CONOCIMIENTO DE EMBARQUE', |
96
|
|
|
903 => 'DOCUMENTO ÚNICO DE SALIDA (DUS)', |
97
|
|
|
904 => 'FACTURA DE TRASPASO', |
98
|
|
|
905 => 'FACTURA DE REEXPEDICIÓN', |
99
|
|
|
906 => 'BOLETAS VENTA MÓDULOS ZF (TODAS)', |
100
|
|
|
907 => 'FACTURAS VENTA MÓDULO ZF (TODAS)', |
101
|
|
|
909 => 'FACTURAS VENTA MÓDULO ZF', |
102
|
|
|
910 => 'SOLICITUD TRASLADO ZONA FRANCA (Z)', |
103
|
|
|
911 => 'DECLARACIÓN DE INGRESO A ZONA FRANCA PRIMARIA', |
104
|
|
|
914 => 'DECLARACIÓN DE INGRESO (DIN)', |
105
|
|
|
919 => 'RESUMEN VENTAS DE NACIONALES PASAJES SIN FACTURA', |
106
|
|
|
920 => 'OTROS REGISTROS NO DOCUMENTADOS (AUMENTA DÉBITO)', |
107
|
|
|
922 => 'OTROS REGISTROS (DISMINUYE DÉBITO)', |
108
|
|
|
924 => 'RESUMEN VENTAS DE INTERNACIONALES PASAJES SIN FACTURA', |
109
|
|
|
// códigos de LibreDTE |
110
|
|
|
0 => 'COTIZACIÓN', |
111
|
|
|
'HES' => 'HOJA DE ENTRADA DE SERVICIOS (HES)', |
112
|
|
|
'EM' => 'Entrada de mercadería (EM)', |
113
|
|
|
]; ///< Glosas para los tipos de documentos (DTE y otros) |
114
|
|
|
|
115
|
|
|
private $formas_pago = [ |
116
|
|
|
1 => 'Contado', |
117
|
|
|
2 => 'Crédito', |
118
|
|
|
3 => 'Sin costo', |
119
|
|
|
]; ///< Glosas de las formas de pago |
120
|
|
|
|
121
|
|
|
private $formas_pago_exportacion = [ |
122
|
|
|
1 => 'Cobranza hasta 1 año', |
123
|
|
|
2 => 'Cobranza más de 1 año', |
124
|
|
|
11 => 'Acreditivo hasta 1 año', |
125
|
|
|
12 => 'Acreditivo más de 1 año', |
126
|
|
|
21 => 'Sin pago', |
127
|
|
|
32 => 'Pago anticipado a la fecha de embarque', |
128
|
|
|
]; ///< Códigos de forma de pago (básicos) de la aduana para exportaciones |
129
|
|
|
|
130
|
|
|
private $detalle_cols = [ |
131
|
|
|
'CdgItem' => ['title'=>'Código', 'align'=>'left', 'width'=>20], |
132
|
|
|
'NmbItem' => ['title'=>'Item', 'align'=>'left', 'width'=>0], |
133
|
|
|
'IndExe' => ['title'=>'IE', 'align'=>'left', 'width'=>'7'], |
134
|
|
|
'QtyItem' => ['title'=>'Cant.', 'align'=>'right', 'width'=>15], |
135
|
|
|
'UnmdItem' => ['title'=>'Unidad', 'align'=>'left', 'width'=>22], |
136
|
|
|
'PrcItem' => ['title'=>'P. unitario', 'align'=>'right', 'width'=>22], |
137
|
|
|
'DescuentoMonto' => ['title'=>'Descuento', 'align'=>'right', 'width'=>22], |
138
|
|
|
'RecargoMonto' => ['title'=>'Recargo', 'align'=>'right', 'width'=>22], |
139
|
|
|
'MontoItem' => ['title'=>'Total item', 'align'=>'right', 'width'=>22], |
140
|
|
|
]; ///< Nombres de columnas detalle, alineación y ancho |
141
|
|
|
|
142
|
|
|
private $item_detalle_posicion = 0; ///< Posición del detalle del item respecto al nombre |
143
|
|
|
private $detalle_fuente = 10; ///< Tamaño de la fuente para el detalle en hoja carta |
144
|
|
|
|
145
|
|
|
private $traslados = [ |
146
|
|
|
1 => 'Operación constituye venta', |
147
|
|
|
2 => 'Ventas por efectuar', |
148
|
|
|
3 => 'Consignaciones', |
149
|
|
|
4 => 'Entrega gratuita', |
150
|
|
|
5 => 'Traslados internos', |
151
|
|
|
6 => 'Otros traslados no venta', |
152
|
|
|
7 => 'Guía de devolución', |
153
|
|
|
8 => 'Traslado para exportación (no venta)', |
154
|
|
|
9 => 'Venta para exportación', |
155
|
|
|
]; ///< Tipos de traslado para guías de despacho |
156
|
|
|
|
157
|
|
|
private $medios_pago = [ |
158
|
|
|
'CH' => 'Cheque', |
159
|
|
|
'CF' => 'Cheque a fecha', |
160
|
|
|
'LT' => 'Letra', |
161
|
|
|
'EF' => 'Efectivo', |
162
|
|
|
'PE' => 'Pago a cuenta corriente', |
163
|
|
|
'TC' => 'Tarjeta de crédito', |
164
|
|
|
'OT' => 'Otro', |
165
|
|
|
]; ///< Medio de pago disponibles |
166
|
|
|
|
167
|
|
|
public static $papel = [ |
168
|
|
|
0 => 'Hoja carta', |
169
|
|
|
57 => 'Papel contínuo 57mm', |
170
|
|
|
75 => 'Papel contínuo 75mm', |
171
|
|
|
80 => 'Papel contínuo 80mm', |
172
|
|
|
]; ///< Tamaño de papel que es soportado |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Constructor de la clase |
176
|
|
|
* @param papelContinuo =true indica que el PDF se generará en formato papel continuo (si se pasa un número será el ancho del PDF en mm) |
177
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
178
|
|
|
* @version 2016-10-06 |
179
|
|
|
*/ |
180
|
|
|
public function __construct($papelContinuo = false) |
181
|
|
|
{ |
182
|
|
|
parent::__construct(); |
183
|
|
|
$this->SetTitle('Documento Tributario Electrónico (DTE) de Chile by LibreDTE'); |
184
|
|
|
$this->papelContinuo = $papelContinuo === true ? 80 : $papelContinuo; |
|
|
|
|
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Método que asigna la ubicación del logo de la empresa |
189
|
|
|
* @param logo URI del logo (puede ser local o en una URL) |
190
|
|
|
* @param posicion Posición respecto a datos del emisor (=0 izq, =1 arriba) |
191
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
192
|
|
|
* @version 2016-08-04 |
193
|
|
|
*/ |
194
|
|
|
public function setLogo($logo, $posicion = 0) |
195
|
|
|
{ |
196
|
|
|
$this->logo = [ |
197
|
|
|
'uri' => $logo, |
198
|
|
|
'posicion' => (int)$posicion, |
199
|
|
|
]; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Método que asigna los datos de la resolución del SII que autoriza al |
204
|
|
|
* emisor a emitir DTEs |
205
|
|
|
* @param resolucion Arreglo con índices NroResol y FchResol |
206
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
207
|
|
|
* @version 2015-09-08 |
208
|
|
|
*/ |
209
|
|
|
public function setResolucion(array $resolucion) |
210
|
|
|
{ |
211
|
|
|
$this->resolucion = $resolucion; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* Método que asigna la página web que se debe utilizar para indicar donde |
216
|
|
|
* se puede verificar el DTE |
217
|
|
|
* @param web Página web donde se puede verificar el documento |
218
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
219
|
|
|
* @version 2015-12-11 |
220
|
|
|
*/ |
221
|
|
|
public function setWebVerificacion($web) |
222
|
|
|
{ |
223
|
|
|
$this->web_verificacion = $web; |
|
|
|
|
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Método que indica si el documento será o no cedible |
228
|
|
|
* @param cedible =true se incorporará leyenda de destino |
229
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
230
|
|
|
* @version 2015-09-09 |
231
|
|
|
*/ |
232
|
|
|
public function setCedible($cedible = true) |
233
|
|
|
{ |
234
|
|
|
$this->cedible = $cedible; |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
/** |
238
|
|
|
* Método que asigna la posición del detalle del Item respecto al nombre |
239
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
240
|
|
|
* @version 2016-08-05 |
241
|
|
|
*/ |
242
|
|
|
public function setPosicionDetalleItem($posicion) |
243
|
|
|
{ |
244
|
|
|
$this->item_detalle_posicion = (int)$posicion; |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* Método que asigna el tamaño de la fuente para el detalle |
249
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
250
|
|
|
* @version 2016-08-03 |
251
|
|
|
*/ |
252
|
|
|
public function setFuenteDetalle($fuente) |
253
|
|
|
{ |
254
|
|
|
$this->detalle_fuente = (int)$fuente; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Método que asigna el ancho e las columnas del detalle desde un arreglo |
259
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
260
|
|
|
* @version 2016-08-03 |
261
|
|
|
*/ |
262
|
|
|
public function setAnchoColumnasDetalle(array $anchos) |
263
|
|
|
{ |
264
|
|
|
foreach ($anchos as $col => $ancho) { |
265
|
|
|
if (isset($this->detalle_cols[$col]) and $ancho) { |
|
|
|
|
266
|
|
|
$this->detalle_cols[$col]['width'] = (int)$ancho; |
267
|
|
|
} |
268
|
|
|
} |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Método que asigna si el tumbre va al pie (por defecto) o va pegado al detalle |
273
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
274
|
|
|
* @version 2017-10-05 |
275
|
|
|
*/ |
276
|
|
|
public function setTimbrePie($timbre_pie = true) |
277
|
|
|
{ |
278
|
|
|
$this->timbre_pie = (bool)$timbre_pie; |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Método que agrega un documento tributario, ya sea en formato de una |
283
|
|
|
* página o papel contínuo según se haya indicado en el constructor |
284
|
|
|
* @param dte Arreglo con los datos del XML (tag Documento) |
285
|
|
|
* @param timbre String XML con el tag TED del DTE |
286
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
287
|
|
|
* @version 2017-07-13 |
288
|
|
|
*/ |
289
|
|
|
public function agregar(array $dte, $timbre = null) |
290
|
|
|
{ |
291
|
|
|
$this->dte = $dte['Encabezado']['IdDoc']['TipoDTE']; |
292
|
|
|
// papel hoja carta |
293
|
|
|
if (!$this->papelContinuo) { |
294
|
|
|
$this->agregarNormal($dte, $timbre); |
295
|
|
|
} |
296
|
|
|
// papel contínuo 57mm |
297
|
|
|
else if ($this->papelContinuo==57) { |
298
|
|
|
$this->agregarContinuo57($dte, $timbre); |
299
|
|
|
} |
300
|
|
|
// papel contínuo 75 o 80mm |
301
|
|
|
else { |
302
|
|
|
$this->agregarContinuo($dte, $timbre, $this->papelContinuo); |
303
|
|
|
} |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
/** |
307
|
|
|
* Método que agrega una página con el documento tributario |
308
|
|
|
* @param dte Arreglo con los datos del XML (tag Documento) |
309
|
|
|
* @param timbre String XML con el tag TED del DTE |
310
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
311
|
|
|
* @version 2017-11-07 |
312
|
|
|
*/ |
313
|
|
|
private function agregarNormal(array $dte, $timbre) |
314
|
|
|
{ |
315
|
|
|
// agregar página para la factura |
316
|
|
|
$this->AddPage(); |
317
|
|
|
// agregar cabecera del documento |
318
|
|
|
$y[] = $this->agregarEmisor($dte['Encabezado']['Emisor']); |
|
|
|
|
319
|
|
|
$y[] = $this->agregarFolio( |
320
|
|
|
$dte['Encabezado']['Emisor']['RUTEmisor'], |
321
|
|
|
$dte['Encabezado']['IdDoc']['TipoDTE'], |
322
|
|
|
$dte['Encabezado']['IdDoc']['Folio'], |
323
|
|
|
!empty($dte['Encabezado']['Emisor']['CmnaOrigen']) ? $dte['Encabezado']['Emisor']['CmnaOrigen'] : null |
324
|
|
|
); |
325
|
|
|
// datos del documento |
326
|
|
|
$this->setY(max($y)); |
327
|
|
|
$this->Ln(); |
328
|
|
|
$y = []; |
329
|
|
|
$y[] = $this->agregarDatosEmision($dte['Encabezado']['IdDoc'], !empty($dte['Encabezado']['Emisor']['CdgVendedor'])?$dte['Encabezado']['Emisor']['CdgVendedor']:null); |
330
|
|
|
$y[] = $this->agregarReceptor($dte['Encabezado']); |
331
|
|
|
$this->setY(max($y)); |
332
|
|
|
$this->agregarTraslado( |
333
|
|
|
!empty($dte['Encabezado']['IdDoc']['IndTraslado']) ? $dte['Encabezado']['IdDoc']['IndTraslado'] : null, |
334
|
|
|
!empty($dte['Encabezado']['Transporte']) ? $dte['Encabezado']['Transporte'] : null |
335
|
|
|
); |
336
|
|
|
if (!empty($dte['Referencia'])) { |
337
|
|
|
$this->agregarReferencia($dte['Referencia']); |
338
|
|
|
} |
339
|
|
|
$this->agregarDetalle($dte['Detalle']); |
340
|
|
|
if (!empty($dte['DscRcgGlobal'])) { |
341
|
|
|
$this->agregarSubTotal($dte['Detalle']); |
342
|
|
|
$this->agregarDescuentosRecargos($dte['DscRcgGlobal']); |
343
|
|
|
} |
344
|
|
View Code Duplication |
if (!empty($dte['Encabezado']['IdDoc']['MntPagos'])) { |
|
|
|
|
345
|
|
|
$this->agregarPagos($dte['Encabezado']['IdDoc']['MntPagos']); |
346
|
|
|
} |
347
|
|
|
// agregar observaciones |
348
|
|
|
$this->x_fin_datos = $this->getY(); |
349
|
|
|
$this->agregarObservacion($dte['Encabezado']['IdDoc']); |
350
|
|
|
if (!$this->timbre_pie) { |
351
|
|
|
$this->Ln(); |
352
|
|
|
} |
353
|
|
|
$this->x_fin_datos = $this->getY(); |
354
|
|
|
$this->agregarTotales($dte['Encabezado']['Totales'], !empty($dte['Encabezado']['OtraMoneda']) ? $dte['Encabezado']['OtraMoneda'] : null); |
355
|
|
|
// agregar timbre |
356
|
|
|
$this->agregarTimbre($timbre); |
357
|
|
|
// agregar acuse de recibo y leyenda cedible |
358
|
|
|
if ($this->cedible and !in_array($dte['Encabezado']['IdDoc']['TipoDTE'], $this->sinAcuseRecibo)) { |
|
|
|
|
359
|
|
|
$this->agregarAcuseRecibo(); |
360
|
|
|
$this->agregarLeyendaDestino($dte['Encabezado']['IdDoc']['TipoDTE']); |
361
|
|
|
} |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* Método que agrega una página con el documento tributario en papel |
366
|
|
|
* contínuo |
367
|
|
|
* @param dte Arreglo con los datos del XML (tag Documento) |
368
|
|
|
* @param timbre String XML con el tag TED del DTE |
369
|
|
|
* @param width Ancho del papel contínuo en mm |
370
|
|
|
* @author Pablo Reyes (https://github.com/pabloxp) |
371
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
372
|
|
|
* @version 2017-10-24 |
373
|
|
|
*/ |
374
|
|
|
private function agregarContinuo(array $dte, $timbre, $width, $height = 0) |
375
|
|
|
{ |
376
|
|
|
// determinar alto de la página y agregarla |
377
|
|
|
$this->logo = null; |
378
|
|
|
$x_start = 1; |
379
|
|
|
$y_start = 1; |
380
|
|
|
$offset = 14; |
381
|
|
|
// determinar alto de la página y agregarla |
382
|
|
|
$this->AddPage('P', [$height ? $height : $this->papel_continuo_alto, $width]); |
383
|
|
|
// agregar cabecera del documento |
384
|
|
|
$y = $this->agregarFolio( |
385
|
|
|
$dte['Encabezado']['Emisor']['RUTEmisor'], |
386
|
|
|
$dte['Encabezado']['IdDoc']['TipoDTE'], |
387
|
|
|
$dte['Encabezado']['IdDoc']['Folio'], |
388
|
|
|
$dte['Encabezado']['Emisor']['CmnaOrigen'], |
389
|
|
|
$x_start, $y_start, $width-($x_start*4), 10, |
390
|
|
|
[0,0,0] |
391
|
|
|
); |
392
|
|
|
$y = $this->agregarEmisor($dte['Encabezado']['Emisor'], $x_start, $y+2, $width-($x_start*4), 8, 9, [0,0,0]); |
393
|
|
|
// datos del documento |
394
|
|
|
$this->SetY($y); |
395
|
|
|
$this->Ln(); |
396
|
|
|
$this->setFont('', '', 8); |
397
|
|
|
$this->agregarDatosEmision($dte['Encabezado']['IdDoc'], !empty($dte['Encabezado']['Emisor']['CdgVendedor'])?$dte['Encabezado']['Emisor']['CdgVendedor']:null, $x_start, $offset, false); |
398
|
|
|
$this->agregarReceptor($dte['Encabezado'], $x_start, $offset); |
399
|
|
|
$this->agregarTraslado( |
400
|
|
|
!empty($dte['Encabezado']['IdDoc']['IndTraslado']) ? $dte['Encabezado']['IdDoc']['IndTraslado'] : null, |
401
|
|
|
!empty($dte['Encabezado']['Transporte']) ? $dte['Encabezado']['Transporte'] : null, |
402
|
|
|
$x_start, $offset |
403
|
|
|
); |
404
|
|
|
if (!empty($dte['Referencia'])) { |
405
|
|
|
$this->agregarReferencia($dte['Referencia'], $x_start, $offset); |
406
|
|
|
} |
407
|
|
|
$this->Ln(); |
408
|
|
|
$this->agregarDetalleContinuo($dte['Detalle']); |
409
|
|
|
if (!empty($dte['DscRcgGlobal'])) { |
410
|
|
|
$this->Ln(); |
411
|
|
|
$this->Ln(); |
412
|
|
|
$this->agregarSubTotal($dte['Detalle'], $x_start); |
413
|
|
|
$this->agregarDescuentosRecargos($dte['DscRcgGlobal'], $x_start); |
414
|
|
|
} |
415
|
|
View Code Duplication |
if (!empty($dte['Encabezado']['IdDoc']['MntPagos'])) { |
|
|
|
|
416
|
|
|
$this->Ln(); |
417
|
|
|
$this->Ln(); |
418
|
|
|
$this->agregarPagos($dte['Encabezado']['IdDoc']['MntPagos'], $x_start); |
419
|
|
|
} |
420
|
|
|
$this->agregarTotales($dte['Encabezado']['Totales'], !empty($dte['Encabezado']['OtraMoneda']) ? $dte['Encabezado']['OtraMoneda'] : null, $this->y+6, 23, 17); |
421
|
|
|
// agregar acuse de recibo y leyenda cedible |
422
|
|
View Code Duplication |
if ($this->cedible and !in_array($dte['Encabezado']['IdDoc']['TipoDTE'], $this->sinAcuseRecibo)) { |
|
|
|
|
423
|
|
|
$this->agregarAcuseReciboContinuo(3, $this->y+6, 68, 34); |
424
|
|
|
$this->agregarLeyendaDestinoContinuo($dte['Encabezado']['IdDoc']['TipoDTE']); |
425
|
|
|
} |
426
|
|
|
// agregar timbre |
427
|
|
|
$y = $this->agregarObservacion($dte['Encabezado']['IdDoc'], $x_start, $this->y+6); |
428
|
|
|
$this->agregarTimbre($timbre, -10, $x_start, $y+6, 70, 6); |
429
|
|
|
// si el alto no se pasó, entonces es con autocálculo, se elimina esta página y se pasa el alto |
430
|
|
|
// que se logró determinar para crear la página con el alto correcto |
431
|
|
View Code Duplication |
if (!$height) { |
|
|
|
|
432
|
|
|
$this->deletePage($this->PageNo()); |
433
|
|
|
$this->agregarContinuo($dte, $timbre, $width, $this->getY()+30); |
434
|
|
|
} |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* Método que agrega una página con el documento tributario |
439
|
|
|
* @param dte Arreglo con los datos del XML (tag Documento) |
440
|
|
|
* @param timbre String XML con el tag TED del DTE |
441
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
442
|
|
|
* @version 2017-10-24 |
443
|
|
|
*/ |
444
|
|
|
private function agregarContinuo57(array $dte, $timbre, $width = 57, $height = 0) |
445
|
|
|
{ |
446
|
|
|
// determinar alto de la página y agregarla |
447
|
|
|
$this->AddPage('P', [$height ? $height : $this->papel_continuo_alto, $width]); |
448
|
|
|
$x = 1; |
449
|
|
|
$y = 5; |
450
|
|
|
$this->SetXY($x,$y); |
451
|
|
|
// agregar datos del documento |
452
|
|
|
$this->setFont('', '', 8); |
453
|
|
|
$this->MultiTexto(!empty($dte['Encabezado']['Emisor']['RznSoc']) ? $dte['Encabezado']['Emisor']['RznSoc'] : $dte['Encabezado']['Emisor']['RznSocEmisor'], $x, null, '', $width-2); |
454
|
|
|
$this->MultiTexto($dte['Encabezado']['Emisor']['RUTEmisor'], $x, null, '', $width-2); |
455
|
|
|
$this->MultiTexto('Giro: '.(!empty($dte['Encabezado']['Emisor']['GiroEmis']) ? $dte['Encabezado']['Emisor']['GiroEmis'] : $dte['Encabezado']['Emisor']['GiroEmisor']), $x, null, '', $width-2); |
456
|
|
|
$this->MultiTexto($dte['Encabezado']['Emisor']['DirOrigen'].', '.$dte['Encabezado']['Emisor']['CmnaOrigen'], $x, null, '', $width-2); |
457
|
|
|
$this->MultiTexto($this->getTipo($dte['Encabezado']['IdDoc']['TipoDTE']).' N° '.$dte['Encabezado']['IdDoc']['Folio'], $x, null, '', $width-2); |
458
|
|
|
$this->MultiTexto('Fecha: '.date('d/m/Y', strtotime($dte['Encabezado']['IdDoc']['FchEmis'])), $x, null, '', $width-2); |
459
|
|
|
// si no es boleta no nominativa se agregan datos receptor |
460
|
|
|
if ($dte['Encabezado']['Receptor']['RUTRecep']!='66666666-6') { |
461
|
|
|
$this->Ln(); |
462
|
|
|
$this->MultiTexto('Receptor: '.$dte['Encabezado']['Receptor']['RUTRecep'], $x, null, '', $width-2); |
463
|
|
|
$this->MultiTexto($dte['Encabezado']['Receptor']['RznSocRecep'], $x, null, '', $width-2); |
464
|
|
|
if (!empty($dte['Encabezado']['Receptor']['GiroRecep'])) { |
465
|
|
|
$this->MultiTexto('Giro: '.$dte['Encabezado']['Receptor']['GiroRecep'], $x, null, '', $width-2); |
466
|
|
|
} |
467
|
|
|
if (!empty($dte['Encabezado']['Receptor']['DirRecep'])) { |
468
|
|
|
$this->MultiTexto($dte['Encabezado']['Receptor']['DirRecep'].', '.$dte['Encabezado']['Receptor']['CmnaRecep'], $x, null, '', $width-2); |
469
|
|
|
} |
470
|
|
|
} |
471
|
|
|
$this->Ln(); |
472
|
|
|
// hay un sólo detalle |
473
|
|
|
if (!isset($dte['Detalle'][0])) { |
474
|
|
|
$this->MultiTexto($dte['Detalle']['NmbItem'].': $'.$this->num($dte['Detalle']['MontoItem']), $x, null, '', $width-2); |
475
|
|
|
} |
476
|
|
|
// hay más de un detalle |
477
|
|
|
else { |
478
|
|
|
foreach ($dte['Detalle'] as $d) { |
479
|
|
|
$this->MultiTexto($d['NmbItem'].': $'.$this->num($d['MontoItem']), $x, null, '', $width-2); |
480
|
|
|
} |
481
|
|
|
if (in_array($dte['Encabezado']['IdDoc']['TipoDTE'], [39, 41])) { |
482
|
|
|
$this->MultiTexto('TOTAL: $'.$this->num($dte['Encabezado']['Totales']['MntTotal']), $x, null, '', $width-2); |
483
|
|
|
} |
484
|
|
|
} |
485
|
|
|
// si no es boleta se coloca EXENTO, NETO, IVA y TOTAL si corresponde |
486
|
|
|
if (!in_array($dte['Encabezado']['IdDoc']['TipoDTE'], [39, 41])) { |
487
|
|
View Code Duplication |
if (!empty($dte['Encabezado']['Totales']['MntExe'])) { |
|
|
|
|
488
|
|
|
$this->MultiTexto('EXENTO: $'.$this->num($dte['Encabezado']['Totales']['MntExe']), $x, null, '', $width-2); |
489
|
|
|
} |
490
|
|
View Code Duplication |
if (!empty($dte['Encabezado']['Totales']['MntNeto'])) { |
|
|
|
|
491
|
|
|
$this->MultiTexto('NETO: $'.$this->num($dte['Encabezado']['Totales']['MntNeto']), $x, null, '', $width-2); |
492
|
|
|
} |
493
|
|
View Code Duplication |
if (!empty($dte['Encabezado']['Totales']['IVA'])) { |
|
|
|
|
494
|
|
|
$this->MultiTexto('IVA: $'.$this->num($dte['Encabezado']['Totales']['IVA']), $x, null, '', $width-2); |
495
|
|
|
} |
496
|
|
|
$this->MultiTexto('TOTAL: $'.$this->num($dte['Encabezado']['Totales']['MntTotal']), $x, null, '', $width-2); |
497
|
|
|
} |
498
|
|
|
// agregar acuse de recibo y leyenda cedible |
499
|
|
View Code Duplication |
if ($this->cedible and !in_array($dte['Encabezado']['IdDoc']['TipoDTE'], $this->sinAcuseRecibo)) { |
|
|
|
|
500
|
|
|
$this->agregarAcuseReciboContinuo(-1, $this->y+6, $width+2, 34); |
501
|
|
|
$this->agregarLeyendaDestinoContinuo($dte['Encabezado']['IdDoc']['TipoDTE']); |
502
|
|
|
} |
503
|
|
|
// agregar timbre |
504
|
|
|
if (!empty($dte['Encabezado']['IdDoc']['TermPagoGlosa'])) { |
505
|
|
|
$this->Ln(); |
506
|
|
|
$this->MultiTexto('Observación: '.$dte['Encabezado']['IdDoc']['TermPagoGlosa']."\n\n", $x); |
507
|
|
|
} |
508
|
|
|
$this->agregarTimbre($timbre, -11, $x, $this->GetY()+6, 55, 6); |
509
|
|
|
// si el alto no se pasó, entonces es con autocálculo, se elimina esta página y se pasa el alto |
510
|
|
|
// que se logró determinar para crear la página con el alto correcto |
511
|
|
View Code Duplication |
if (!$height) { |
|
|
|
|
512
|
|
|
$this->deletePage($this->PageNo()); |
513
|
|
|
$this->agregarContinuo57($dte, $timbre, $width, $this->getY()+30); |
514
|
|
|
} |
515
|
|
|
} |
516
|
|
|
|
517
|
|
|
/** |
518
|
|
|
* Método que agrega los datos de la empresa |
519
|
|
|
* Orden de los datos: |
520
|
|
|
* - Razón social del emisor |
521
|
|
|
* - Giro del emisor (sin abreviar) |
522
|
|
|
* - Dirección casa central del emisor |
523
|
|
|
* - Dirección sucursales |
524
|
|
|
* @param emisor Arreglo con los datos del emisor (tag Emisor del XML) |
525
|
|
|
* @param x Posición horizontal de inicio en el PDF |
526
|
|
|
* @param y Posición vertical de inicio en el PDF |
527
|
|
|
* @param w Ancho de la información del emisor |
528
|
|
|
* @param w_img Ancho máximo de la imagen |
529
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
530
|
|
|
* @version 2018-04-13 |
531
|
|
|
*/ |
532
|
|
|
protected function agregarEmisor(array $emisor, $x = 10, $y = 15, $w = 75, $w_img = 30, $font_size = null, array $color = null) |
533
|
|
|
{ |
534
|
|
|
// logo del documento |
535
|
|
|
if (isset($this->logo)) { |
536
|
|
|
$this->Image( |
537
|
|
|
$this->logo['uri'], |
538
|
|
|
$x, |
539
|
|
|
$y, |
540
|
|
|
!$this->logo['posicion']?$w_img:null, $this->logo['posicion']?($w_img/2):null, |
541
|
|
|
'PNG', |
542
|
|
|
(isset($emisor['url'])?$emisor['url']:''), |
543
|
|
|
'T' |
544
|
|
|
); |
545
|
|
|
if ($this->logo['posicion']) { |
546
|
|
|
$this->SetY($this->y + ($w_img/2)); |
547
|
|
|
$w += 40; |
548
|
|
|
} else { |
549
|
|
|
$x = $this->x+3; |
550
|
|
|
} |
551
|
|
|
} else { |
552
|
|
|
$this->y = $y-2; |
553
|
|
|
$w += 40; |
554
|
|
|
} |
555
|
|
|
// agregar datos del emisor |
556
|
|
|
$this->setFont('', 'B', $font_size ? $font_size : 14); |
557
|
|
|
$this->SetTextColorArray($color===null?[32, 92, 144]:$color); |
558
|
|
|
$this->MultiTexto(!empty($emisor['RznSoc']) ? $emisor['RznSoc'] : $emisor['RznSocEmisor'], $x, $this->y+2, 'L', $w); |
559
|
|
|
$this->setFont('', 'B', $font_size ? $font_size : 9); |
560
|
|
|
$this->SetTextColorArray([0,0,0]); |
561
|
|
|
$this->MultiTexto(!empty($emisor['GiroEmis']) ? $emisor['GiroEmis'] : $emisor['GiroEmisor'], $x, $this->y, 'L', $w); |
562
|
|
|
$comuna = !empty($emisor['CmnaOrigen']) ? $emisor['CmnaOrigen'] : null; |
563
|
|
|
$ciudad = !empty($emisor['CiudadOrigen']) ? $emisor['CiudadOrigen'] : \sasco\LibreDTE\Chile::getCiudad($comuna); |
564
|
|
|
$this->MultiTexto($emisor['DirOrigen'].($comuna?(', '.$comuna):'').($ciudad?(', '.$ciudad):''), $x, $this->y, 'L', $w); |
565
|
|
|
if (!empty($emisor['Sucursal'])) { |
566
|
|
|
$this->MultiTexto('Sucursal: '.$emisor['Sucursal'], $x, $this->y, 'L', $w); |
567
|
|
|
} |
568
|
|
|
$contacto = []; |
569
|
|
|
if (!empty($emisor['Telefono'])) { |
570
|
|
|
if (!is_array($emisor['Telefono'])) |
571
|
|
|
$emisor['Telefono'] = [$emisor['Telefono']]; |
572
|
|
|
foreach ($emisor['Telefono'] as $t) |
573
|
|
|
$contacto[] = $t; |
574
|
|
|
} |
575
|
|
|
if (!empty($emisor['CorreoEmisor'])) { |
576
|
|
|
$contacto[] = $emisor['CorreoEmisor']; |
577
|
|
|
} |
578
|
|
|
if ($contacto) { |
|
|
|
|
579
|
|
|
$this->MultiTexto(implode(' / ', $contacto), $x, $this->y, 'L', $w); |
580
|
|
|
} |
581
|
|
|
return $this->y; |
582
|
|
|
} |
583
|
|
|
|
584
|
|
|
/** |
585
|
|
|
* Método que agrega el recuadro con el folio |
586
|
|
|
* Recuadro: |
587
|
|
|
* - Tamaño mínimo 1.5x5.5 cms |
588
|
|
|
* - En lado derecho (negro o rojo) |
589
|
|
|
* - Enmarcado por una línea de entre 0.5 y 1 mm de espesor |
590
|
|
|
* - Tamaño máximo 4x8 cms |
591
|
|
|
* - Letras tamaño 10 o superior en mayúsculas y negritas |
592
|
|
|
* - Datos del recuadro: RUT emisor, nombre de documento en 2 líneas, |
593
|
|
|
* folio. |
594
|
|
|
* - Bajo el recuadro indicar la Dirección regional o Unidad del SII a la |
595
|
|
|
* que pertenece el emisor |
596
|
|
|
* @param rut RUT del emisor |
597
|
|
|
* @param tipo Código o glosa del tipo de documento |
598
|
|
|
* @param sucursal_sii Código o glosa de la sucursal del SII del Emisor |
599
|
|
|
* @param x Posición horizontal de inicio en el PDF |
600
|
|
|
* @param y Posición vertical de inicio en el PDF |
601
|
|
|
* @param w Ancho de la información del emisor |
602
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
603
|
|
|
* @version 2016-12-02 |
604
|
|
|
*/ |
605
|
|
|
protected function agregarFolio($rut, $tipo, $folio, $sucursal_sii = null, $x = 130, $y = 15, $w = 70, $font_size = null, array $color = null) |
606
|
|
|
{ |
607
|
|
|
if ($color===null) { |
608
|
|
|
$color = $tipo ? ($tipo==52 ? [0,172,140] : [255,0,0]) : [0,0,0]; |
609
|
|
|
} |
610
|
|
|
$this->SetTextColorArray($color); |
611
|
|
|
// colocar rut emisor, glosa documento y folio |
612
|
|
|
list($rut, $dv) = explode('-', $rut); |
613
|
|
|
$this->setFont ('', 'B', $font_size ? $font_size : 15); |
614
|
|
|
$this->MultiTexto('R.U.T.: '.$this->num($rut).'-'.$dv, $x, $y+4, 'C', $w); |
615
|
|
|
$this->setFont('', 'B', $font_size ? $font_size : 12); |
616
|
|
|
$this->MultiTexto($this->getTipo($tipo), $x, null, 'C', $w); |
617
|
|
|
$this->setFont('', 'B', $font_size ? $font_size : 15); |
618
|
|
|
$this->MultiTexto('N° '.$folio, $x, null, 'C', $w); |
619
|
|
|
// dibujar rectángulo rojo |
620
|
|
|
$this->Rect($x, $y, $w, round($this->getY()-$y+3), 'D', ['all' => ['width' => 0.5, 'color' => $color]]); |
621
|
|
|
// colocar unidad del SII |
622
|
|
|
$this->setFont('', 'B', $font_size ? $font_size : 10); |
623
|
|
|
if ($tipo) { |
624
|
|
|
$this->Texto('S.I.I. - '.\sasco\LibreDTE\Sii::getDireccionRegional($sucursal_sii), $x, $this->getY()+4, 'C', $w); |
|
|
|
|
625
|
|
|
} |
626
|
|
|
$this->SetTextColorArray([0,0,0]); |
627
|
|
|
$this->Ln(); |
628
|
|
|
return $this->y; |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
/** |
632
|
|
|
* Método que entrega la glosa del tipo de documento |
633
|
|
|
* @param tipo Código del tipo de documento |
634
|
|
|
* @return Glosa del tipo de documento |
635
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
636
|
|
|
* @version 2016-11-18 |
637
|
|
|
*/ |
638
|
|
|
private function getTipo($tipo) |
639
|
|
|
{ |
640
|
|
|
if (!is_numeric($tipo) and !isset($this->tipos[$tipo])) { |
|
|
|
|
641
|
|
|
return $tipo; |
642
|
|
|
} |
643
|
|
|
return isset($this->tipos[$tipo]) ? strtoupper($this->tipos[$tipo]) : 'Documento '.$tipo; |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
/** |
647
|
|
|
* Método que agrega los datos de la emisión del DTE que no son los dato del |
648
|
|
|
* receptor |
649
|
|
|
* @param IdDoc Información general del documento |
650
|
|
|
* @param x Posición horizontal de inicio en el PDF |
651
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
652
|
|
|
* @version 2017-06-15 |
653
|
|
|
*/ |
654
|
|
|
protected function agregarDatosEmision($IdDoc, $CdgVendedor, $x = 10, $offset = 22, $mostrar_dia = true) |
655
|
|
|
{ |
656
|
|
|
// si es hoja carta |
657
|
|
|
if ($x==10) { |
658
|
|
|
$y = $this->GetY(); |
659
|
|
|
// fecha emisión |
660
|
|
|
$this->setFont('', 'B', null); |
661
|
|
|
$this->MultiTexto($this->date($IdDoc['FchEmis'], $mostrar_dia), $x, null, 'R'); |
662
|
|
|
$this->setFont('', '', null); |
663
|
|
|
// período facturación |
664
|
|
|
if (!empty($IdDoc['PeriodoDesde']) and !empty($IdDoc['PeriodoHasta'])) { |
|
|
|
|
665
|
|
|
$this->MultiTexto('Período del '.date('d/m/y', strtotime($IdDoc['PeriodoDesde'])).' al '.date('d/m/y', strtotime($IdDoc['PeriodoHasta'])), $x, null, 'R'); |
666
|
|
|
} |
667
|
|
|
// pago anticicado |
668
|
|
View Code Duplication |
if (!empty($IdDoc['FchCancel'])) { |
|
|
|
|
669
|
|
|
$this->MultiTexto('Pagado el '.$this->date($IdDoc['FchCancel'], false), $x, null, 'R'); |
670
|
|
|
} |
671
|
|
|
// fecha vencimiento |
672
|
|
View Code Duplication |
if (!empty($IdDoc['FchVenc'])) { |
|
|
|
|
673
|
|
|
$this->MultiTexto('Vence el '.$this->date($IdDoc['FchVenc'], false), $x, null, 'R'); |
674
|
|
|
} |
675
|
|
|
// forma de pago nacional |
676
|
|
View Code Duplication |
if (!empty($IdDoc['FmaPago'])) { |
|
|
|
|
677
|
|
|
$this->MultiTexto('Venta: '.strtolower($this->formas_pago[$IdDoc['FmaPago']]), $x, null, 'R'); |
678
|
|
|
} |
679
|
|
|
// forma de pago exportación |
680
|
|
View Code Duplication |
if (!empty($IdDoc['FmaPagExp'])) { |
|
|
|
|
681
|
|
|
$this->MultiTexto('Venta: '.strtolower($this->formas_pago_exportacion[$IdDoc['FmaPagExp']]), $x, null, 'R'); |
682
|
|
|
} |
683
|
|
|
// vendedor |
684
|
|
|
if (!empty($CdgVendedor)) { |
685
|
|
|
$this->MultiTexto('Vendedor: '.$CdgVendedor, $x, null, 'R'); |
686
|
|
|
} |
687
|
|
|
$y_end = $this->GetY(); |
688
|
|
|
$this->SetY($y); |
689
|
|
|
} |
690
|
|
|
// papel contínuo |
691
|
|
|
else { |
692
|
|
|
// fecha de emisión |
693
|
|
|
$this->setFont('', 'B', null); |
694
|
|
|
$this->Texto('Emisión', $x); |
695
|
|
|
$this->Texto(':', $x+$offset); |
696
|
|
|
$this->setFont('', '', null); |
697
|
|
|
$this->MultiTexto($this->date($IdDoc['FchEmis'], $mostrar_dia), $x+$offset+2); |
698
|
|
|
// forma de pago nacional |
699
|
|
|
if (!empty($IdDoc['FmaPago'])) { |
700
|
|
|
$this->setFont('', 'B', null); |
701
|
|
|
$this->Texto('Venta', $x); |
702
|
|
|
$this->Texto(':', $x+$offset); |
703
|
|
|
$this->setFont('', '', null); |
704
|
|
|
$this->MultiTexto($this->formas_pago[$IdDoc['FmaPago']], $x+$offset+2); |
705
|
|
|
} |
706
|
|
|
// forma de pago exportación |
707
|
|
|
if (!empty($IdDoc['FmaPagExp'])) { |
708
|
|
|
$this->setFont('', 'B', null); |
709
|
|
|
$this->Texto('Venta', $x); |
710
|
|
|
$this->Texto(':', $x+$offset); |
711
|
|
|
$this->setFont('', '', null); |
712
|
|
|
$this->MultiTexto($this->formas_pago_exportacion[$IdDoc['FmaPagExp']], $x+$offset+2); |
713
|
|
|
} |
714
|
|
|
// pago anticicado |
715
|
|
|
if (!empty($IdDoc['FchCancel'])) { |
716
|
|
|
$this->setFont('', 'B', null); |
717
|
|
|
$this->Texto('Pagado el', $x); |
718
|
|
|
$this->Texto(':', $x+$offset); |
719
|
|
|
$this->setFont('', '', null); |
720
|
|
|
$this->MultiTexto($this->date($IdDoc['FchCancel'], $mostrar_dia), $x+$offset+2); |
721
|
|
|
} |
722
|
|
|
// fecha vencimiento |
723
|
|
|
if (!empty($IdDoc['FchVenc'])) { |
724
|
|
|
$this->setFont('', 'B', null); |
725
|
|
|
$this->Texto('Vence el', $x); |
726
|
|
|
$this->Texto(':', $x+$offset); |
727
|
|
|
$this->setFont('', '', null); |
728
|
|
|
$this->MultiTexto($this->date($IdDoc['FchVenc'], $mostrar_dia), $x+$offset+2); |
729
|
|
|
} |
730
|
|
|
$y_end = $this->GetY(); |
731
|
|
|
} |
732
|
|
|
return $y_end; |
733
|
|
|
} |
734
|
|
|
|
735
|
|
|
/** |
736
|
|
|
* Método que agrega los datos del receptor |
737
|
|
|
* @param receptor Arreglo con los datos del receptor (tag Receptor del XML) |
738
|
|
|
* @param x Posición horizontal de inicio en el PDF |
739
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
740
|
|
|
* @version 2017-06-15 |
741
|
|
|
*/ |
742
|
|
|
protected function agregarReceptor(array $Encabezado, $x = 10, $offset = 22) |
743
|
|
|
{ |
744
|
|
|
$receptor = $Encabezado['Receptor']; |
745
|
|
View Code Duplication |
if (!empty($receptor['RUTRecep']) and $receptor['RUTRecep']!='66666666-6') { |
|
|
|
|
746
|
|
|
list($rut, $dv) = explode('-', $receptor['RUTRecep']); |
747
|
|
|
$this->setFont('', 'B', null); |
748
|
|
|
$this->Texto('R.U.T.', $x); |
749
|
|
|
$this->Texto(':', $x+$offset); |
750
|
|
|
$this->setFont('', '', null); |
751
|
|
|
$this->MultiTexto($this->num($rut).'-'.$dv, $x+$offset+2); |
752
|
|
|
} |
753
|
|
View Code Duplication |
if (!empty($receptor['RznSocRecep'])) { |
|
|
|
|
754
|
|
|
$this->setFont('', 'B', null); |
755
|
|
|
$this->Texto('Señor(es)', $x); |
756
|
|
|
$this->Texto(':', $x+$offset); |
757
|
|
|
$this->setFont('', '', null); |
758
|
|
|
$this->MultiTexto($receptor['RznSocRecep'], $x+$offset+2, null, '', $x==10?105:0); |
759
|
|
|
} |
760
|
|
View Code Duplication |
if (!empty($receptor['GiroRecep'])) { |
|
|
|
|
761
|
|
|
$this->setFont('', 'B', null); |
762
|
|
|
$this->Texto('Giro', $x); |
763
|
|
|
$this->Texto(':', $x+$offset); |
764
|
|
|
$this->setFont('', '', null); |
765
|
|
|
$this->MultiTexto($receptor['GiroRecep'], $x+$offset+2); |
766
|
|
|
} |
767
|
|
|
if (!empty($receptor['DirRecep'])) { |
768
|
|
|
$this->setFont('', 'B', null); |
769
|
|
|
$this->Texto('Dirección', $x); |
770
|
|
|
$this->Texto(':', $x+$offset); |
771
|
|
|
$this->setFont('', '', null); |
772
|
|
|
$ciudad = !empty($receptor['CiudadRecep']) ? $receptor['CiudadRecep'] : ( |
773
|
|
|
!empty($receptor['CmnaRecep']) ? \sasco\LibreDTE\Chile::getCiudad($receptor['CmnaRecep']) : '' |
774
|
|
|
); |
775
|
|
|
$this->MultiTexto($receptor['DirRecep'].(!empty($receptor['CmnaRecep'])?(', '.$receptor['CmnaRecep']):'').($ciudad?(', '.$ciudad):''), $x+$offset+2); |
776
|
|
|
} |
777
|
|
|
if (!empty($receptor['Extranjero']['Nacionalidad'])) { |
778
|
|
|
$this->setFont('', 'B', null); |
779
|
|
|
$this->Texto('Nacionalidad', $x); |
780
|
|
|
$this->Texto(':', $x+$offset); |
781
|
|
|
$this->setFont('', '', null); |
782
|
|
|
$this->MultiTexto(\sasco\LibreDTE\Sii\Aduana::getNacionalidad($receptor['Extranjero']['Nacionalidad']), $x+$offset+2); |
783
|
|
|
} |
784
|
|
|
if (!empty($receptor['Extranjero']['NumId'])) { |
785
|
|
|
$this->setFont('', 'B', null); |
786
|
|
|
$this->Texto('N° ID extranj.', $x); |
787
|
|
|
$this->Texto(':', $x+$offset); |
788
|
|
|
$this->setFont('', '', null); |
789
|
|
|
$this->MultiTexto($receptor['Extranjero']['NumId'], $x+$offset+2); |
790
|
|
|
} |
791
|
|
|
$contacto = []; |
792
|
|
|
if (!empty($receptor['Contacto'])) |
793
|
|
|
$contacto[] = $receptor['Contacto']; |
794
|
|
|
if (!empty($receptor['CorreoRecep'])) |
795
|
|
|
$contacto[] = $receptor['CorreoRecep']; |
796
|
|
View Code Duplication |
if (!empty($contacto)) { |
|
|
|
|
797
|
|
|
$this->setFont('', 'B', null); |
798
|
|
|
$this->Texto('Contacto', $x); |
799
|
|
|
$this->Texto(':', $x+$offset); |
800
|
|
|
$this->setFont('', '', null); |
801
|
|
|
$this->MultiTexto(implode(' / ', $contacto), $x+$offset+2); |
802
|
|
|
} |
803
|
|
View Code Duplication |
if (!empty($Encabezado['RUTSolicita'])) { |
|
|
|
|
804
|
|
|
list($rut, $dv) = explode('-', $Encabezado['RUTSolicita']); |
805
|
|
|
$this->setFont('', 'B', null); |
806
|
|
|
$this->Texto('RUT solicita', $x); |
807
|
|
|
$this->Texto(':', $x+$offset); |
808
|
|
|
$this->setFont('', '', null); |
809
|
|
|
$this->MultiTexto($this->num($rut).'-'.$dv, $x+$offset+2); |
810
|
|
|
} |
811
|
|
View Code Duplication |
if (!empty($receptor['CdgIntRecep'])) { |
|
|
|
|
812
|
|
|
$this->setFont('', 'B', null); |
813
|
|
|
$this->Texto('Cód. recep.', $x); |
814
|
|
|
$this->Texto(':', $x+$offset); |
815
|
|
|
$this->setFont('', '', null); |
816
|
|
|
$this->MultiTexto($receptor['CdgIntRecep'], $x+$offset+2, null, '', $x==10?105:0); |
817
|
|
|
} |
818
|
|
|
return $this->GetY(); |
819
|
|
|
} |
820
|
|
|
|
821
|
|
|
/** |
822
|
|
|
* Método que agrega los datos del traslado |
823
|
|
|
* @param IndTraslado |
824
|
|
|
* @param Transporte |
825
|
|
|
* @param x Posición horizontal de inicio en el PDF |
826
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
827
|
|
|
* @version 2016-08-03 |
828
|
|
|
*/ |
829
|
|
|
protected function agregarTraslado($IndTraslado, array $Transporte = null, $x = 10, $offset = 22) |
830
|
|
|
{ |
831
|
|
|
// agregar tipo de traslado |
832
|
|
View Code Duplication |
if ($IndTraslado) { |
|
|
|
|
833
|
|
|
$this->setFont('', 'B', null); |
834
|
|
|
$this->Texto('Tipo oper.', $x); |
835
|
|
|
$this->Texto(':', $x+$offset); |
836
|
|
|
$this->setFont('', '', null); |
837
|
|
|
$this->MultiTexto($this->traslados[$IndTraslado], $x+$offset+2); |
838
|
|
|
} |
839
|
|
|
// agregar información de transporte |
840
|
|
|
if ($Transporte) { |
841
|
|
|
$transporte = ''; |
842
|
|
|
if (!empty($Transporte['DirDest']) and !empty($Transporte['CmnaDest'])) { |
|
|
|
|
843
|
|
|
$transporte .= 'a '.$Transporte['DirDest'].', '.$Transporte['CmnaDest']; |
844
|
|
|
} |
845
|
|
|
if (!empty($Transporte['RUTTrans'])) |
846
|
|
|
$transporte .= ' por '.$Transporte['RUTTrans']; |
847
|
|
|
if (!empty($Transporte['Patente'])) |
848
|
|
|
$transporte .= ' en vehículo '.$Transporte['Patente']; |
849
|
|
|
if (isset($Transporte['Chofer']) and is_array($Transporte['Chofer'])) { |
|
|
|
|
850
|
|
View Code Duplication |
if (!empty($Transporte['Chofer']['NombreChofer'])) |
|
|
|
|
851
|
|
|
$transporte .= ' con chofer '.$Transporte['Chofer']['NombreChofer']; |
852
|
|
View Code Duplication |
if (!empty($Transporte['Chofer']['RUTChofer'])) |
|
|
|
|
853
|
|
|
$transporte .= ' ('.$Transporte['Chofer']['RUTChofer'].')'; |
854
|
|
|
} |
855
|
|
View Code Duplication |
if ($transporte) { |
|
|
|
|
856
|
|
|
$this->setFont('', 'B', null); |
857
|
|
|
$this->Texto('Traslado', $x); |
858
|
|
|
$this->Texto(':', $x+$offset); |
859
|
|
|
$this->setFont('', '', null); |
860
|
|
|
$this->MultiTexto(ucfirst(trim($transporte)), $x+$offset+2); |
861
|
|
|
} |
862
|
|
|
} |
863
|
|
|
// agregar información de aduana |
864
|
|
|
if (!empty($Transporte['Aduana']) and is_array($Transporte['Aduana'])) { |
|
|
|
|
865
|
|
|
$col = 0; |
866
|
|
|
foreach ($Transporte['Aduana'] as $tag => $codigo) { |
867
|
|
|
if ($codigo===false) |
868
|
|
|
continue; |
869
|
|
|
$glosa = \sasco\LibreDTE\Sii\Aduana::getGlosa($tag); |
870
|
|
|
$valor = \sasco\LibreDTE\Sii\Aduana::getValor($tag, $codigo); |
871
|
|
|
if ($glosa!==false and $valor!==false) { |
|
|
|
|
872
|
|
|
if ($tag=='TipoBultos' and $col) { |
|
|
|
|
873
|
|
|
$col = abs($col-110); |
874
|
|
|
$this->Ln(); |
875
|
|
|
} |
876
|
|
|
$this->setFont('', 'B', null); |
877
|
|
|
$this->Texto($glosa, $x+$col); |
878
|
|
|
$this->Texto(':', $x+$offset+$col); |
879
|
|
|
$this->setFont('', '', null); |
880
|
|
|
$this->Texto($valor, $x+$offset+2+$col); |
881
|
|
|
if ($tag=='TipoBultos') |
882
|
|
|
$col = abs($col-110); |
883
|
|
|
if ($col) |
884
|
|
|
$this->Ln(); |
885
|
|
|
$col = abs($col-110); |
886
|
|
|
} |
887
|
|
|
} |
888
|
|
|
if ($col) |
889
|
|
|
$this->Ln(); |
890
|
|
|
} |
891
|
|
|
} |
892
|
|
|
|
893
|
|
|
/** |
894
|
|
|
* Método que agrega las referencias del documento |
895
|
|
|
* @param referencias Arreglo con las referencias del documento (tag Referencia del XML) |
896
|
|
|
* @param x Posición horizontal de inicio en el PDF |
897
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
898
|
|
|
* @version 2017-09-25 |
899
|
|
|
*/ |
900
|
|
|
protected function agregarReferencia($referencias, $x = 10, $offset = 22) |
901
|
|
|
{ |
902
|
|
|
if (!isset($referencias[0])) |
903
|
|
|
$referencias = [$referencias]; |
904
|
|
|
foreach($referencias as $r) { |
905
|
|
|
$texto = $r['NroLinRef'].' - '; |
906
|
|
|
if (!empty($r['TpoDocRef'])) { |
907
|
|
|
$texto .= $this->getTipo($r['TpoDocRef']).' '; |
908
|
|
|
} |
909
|
|
|
if (!empty($r['FolioRef'])) { |
910
|
|
|
if (is_numeric($r['FolioRef'])) { |
911
|
|
|
$texto .= ' N° '.$r['FolioRef'].' '; |
912
|
|
|
} else { |
913
|
|
|
$texto .= ' '.$r['FolioRef'].' '; |
914
|
|
|
} |
915
|
|
|
} |
916
|
|
|
if (!empty($r['FchRef'])) { |
917
|
|
|
$texto .= 'del '.date('d/m/Y', strtotime($r['FchRef'])); |
918
|
|
|
} |
919
|
|
|
if (isset($r['RazonRef']) and $r['RazonRef']!==false) { |
|
|
|
|
920
|
|
|
$texto = $texto.': '.$r['RazonRef']; |
921
|
|
|
} |
922
|
|
|
$this->setFont('', 'B', null); |
923
|
|
|
$this->Texto('Referencia', $x); |
924
|
|
|
$this->Texto(':', $x+$offset); |
925
|
|
|
$this->setFont('', '', null); |
926
|
|
|
$this->MultiTexto($texto, $x+$offset+2); |
927
|
|
|
} |
928
|
|
|
} |
929
|
|
|
|
930
|
|
|
/** |
931
|
|
|
* Método que agrega el detalle del documento |
932
|
|
|
* @param detalle Arreglo con el detalle del documento (tag Detalle del XML) |
933
|
|
|
* @param x Posición horizontal de inicio en el PDF |
934
|
|
|
* @param y Posición vertical de inicio en el PDF |
935
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
936
|
|
|
* @version 2016-08-05 |
937
|
|
|
*/ |
938
|
|
|
protected function agregarDetalle($detalle, $x = 10) |
939
|
|
|
{ |
940
|
|
|
if (!isset($detalle[0])) |
941
|
|
|
$detalle = [$detalle]; |
942
|
|
|
$this->setFont('', '', $this->detalle_fuente); |
943
|
|
|
// titulos |
944
|
|
|
$titulos = []; |
945
|
|
|
$titulos_keys = array_keys($this->detalle_cols); |
946
|
|
|
foreach ($this->detalle_cols as $key => $info) { |
947
|
|
|
$titulos[$key] = $info['title']; |
948
|
|
|
} |
949
|
|
|
// normalizar cada detalle |
950
|
|
|
$dte_exento = in_array($this->dte, [34, 110, 111, 112]); |
951
|
|
|
foreach ($detalle as &$item) { |
952
|
|
|
// quitar columnas |
953
|
|
|
foreach ($item as $col => $valor) { |
954
|
|
|
if ($col=='DscItem' and !empty($item['DscItem'])) { |
|
|
|
|
955
|
|
|
$item['NmbItem'] .= !$this->item_detalle_posicion ? '<br/>' : ': '; |
956
|
|
|
$item['NmbItem'] .= '<span style="font-size:0.7em">'.$item['DscItem'].'</span>'; |
957
|
|
|
} |
958
|
|
|
if (!in_array($col, $titulos_keys) or ($dte_exento and $col=='IndExe')) |
|
|
|
|
959
|
|
|
unset($item[$col]); |
960
|
|
|
} |
961
|
|
|
// ajustes a IndExe |
962
|
|
|
if (isset($item['IndExe'])) { |
963
|
|
|
if ($item['IndExe']==1) |
964
|
|
|
$item['IndExe'] = 'EX'; |
965
|
|
|
else if ($item['IndExe']==2) |
966
|
|
|
$item['IndExe'] = 'NF'; |
967
|
|
|
} |
968
|
|
|
// agregar todas las columnas que se podrían imprimir en la tabla |
969
|
|
|
$item_default = []; |
970
|
|
|
foreach ($this->detalle_cols as $key => $info) |
971
|
|
|
$item_default[$key] = false; |
972
|
|
|
$item = array_merge($item_default, $item); |
973
|
|
|
// si hay código de item se extrae su valor |
974
|
|
|
if ($item['CdgItem']) |
975
|
|
|
$item['CdgItem'] = $item['CdgItem']['VlrCodigo']; |
976
|
|
|
// dar formato a números |
977
|
|
|
foreach (['QtyItem', 'PrcItem', 'DescuentoMonto', 'RecargoMonto', 'MontoItem'] as $col) { |
978
|
|
|
if ($item[$col]) |
979
|
|
|
$item[$col] = $this->num($item[$col]); |
980
|
|
|
} |
981
|
|
|
} |
982
|
|
|
// opciones |
983
|
|
|
$options = ['align'=>[]]; |
984
|
|
|
$i = 0; |
985
|
|
|
foreach ($this->detalle_cols as $info) { |
986
|
|
|
if (isset($info['width'])) |
987
|
|
|
$options['width'][$i] = $info['width']; |
988
|
|
|
$options['align'][$i] = $info['align']; |
989
|
|
|
$i++; |
990
|
|
|
} |
991
|
|
|
// agregar tabla de detalle |
992
|
|
|
$this->Ln(); |
993
|
|
|
$this->SetX($x); |
994
|
|
|
$this->addTableWithoutEmptyCols($titulos, $detalle, $options); |
995
|
|
|
} |
996
|
|
|
|
997
|
|
|
/** |
998
|
|
|
* Método que agrega el detalle del documento |
999
|
|
|
* @param detalle Arreglo con el detalle del documento (tag Detalle del XML) |
1000
|
|
|
* @param x Posición horizontal de inicio en el PDF |
1001
|
|
|
* @param y Posición vertical de inicio en el PDF |
1002
|
|
|
* @author Pablo Reyes (https://github.com/pabloxp) |
1003
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1004
|
|
|
* @version 2016-12-13 |
1005
|
|
|
*/ |
1006
|
|
|
protected function agregarDetalleContinuo($detalle, $x = 3) |
1007
|
|
|
{ |
1008
|
|
|
$this->SetY($this->getY()+1); |
1009
|
|
|
$p1x = $x; |
1010
|
|
|
$p1y = $this->y; |
1011
|
|
|
$p2x = $this->getPageWidth() - 2; |
1012
|
|
|
$p2y = $p1y; // Use same y for a straight line |
1013
|
|
|
$style = array('width' => 0.2,'color' => array(0, 0, 0)); |
1014
|
|
|
$this->Line($p1x, $p1y, $p2x, $p2y, $style); |
1015
|
|
|
$this->Texto($this->detalle_cols['NmbItem']['title'], $x+1, $this->y, ucfirst($this->detalle_cols['NmbItem']['align'][0]), $this->detalle_cols['NmbItem']['width']); |
1016
|
|
|
$this->Texto($this->detalle_cols['PrcItem']['title'], $x+15, $this->y, ucfirst($this->detalle_cols['PrcItem']['align'][0]), $this->detalle_cols['PrcItem']['width']); |
1017
|
|
|
$this->Texto($this->detalle_cols['QtyItem']['title'], $x+35, $this->y, ucfirst($this->detalle_cols['QtyItem']['align'][0]), $this->detalle_cols['QtyItem']['width']); |
1018
|
|
|
$this->Texto($this->detalle_cols['MontoItem']['title'], $x+45, $this->y, ucfirst($this->detalle_cols['MontoItem']['align'][0]), $this->detalle_cols['MontoItem']['width']); |
1019
|
|
|
$this->Line($p1x, $p1y+4, $p2x, $p2y+4, $style); |
1020
|
|
|
if (!isset($detalle[0])) |
1021
|
|
|
$detalle = [$detalle]; |
1022
|
|
|
$this->SetY($this->getY()+2); |
1023
|
|
|
foreach($detalle as &$d) { |
1024
|
|
|
$this->MultiTexto($d['NmbItem'], $x+1, $this->y+4, ucfirst($this->detalle_cols['NmbItem']['align'][0]), $this->detalle_cols['NmbItem']['width']); |
1025
|
|
|
$this->Texto(number_format($d['PrcItem'],0,',','.'), $x+15, $this->y, ucfirst($this->detalle_cols['PrcItem']['align'][0]), $this->detalle_cols['PrcItem']['width']); |
1026
|
|
|
$this->Texto($this->num($d['QtyItem']), $x+35, $this->y, ucfirst($this->detalle_cols['QtyItem']['align'][0]), $this->detalle_cols['QtyItem']['width']); |
1027
|
|
|
$this->Texto($this->num($d['MontoItem']), $x+45, $this->y, ucfirst($this->detalle_cols['MontoItem']['align'][0]), $this->detalle_cols['MontoItem']['width']); |
1028
|
|
|
} |
1029
|
|
|
$this->Line($p1x, $this->y+4, $p2x, $this->y+4, $style); |
1030
|
|
|
} |
1031
|
|
|
|
1032
|
|
|
/** |
1033
|
|
|
* Método que agrega el subtotal del DTE |
1034
|
|
|
* @param detalle Arreglo con los detalles del documentos para poder |
1035
|
|
|
* calcular subtotal |
1036
|
|
|
* @param x Posición horizontal de inicio en el PDF |
1037
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1038
|
|
|
* @version 2016-08-17 |
1039
|
|
|
*/ |
1040
|
|
|
protected function agregarSubTotal(array $detalle, $x = 10) { |
1041
|
|
|
$subtotal = 0; |
1042
|
|
|
if (!isset($detalle[0])) { |
1043
|
|
|
$detalle = [$detalle]; |
1044
|
|
|
} |
1045
|
|
|
foreach($detalle as &$d) { |
1046
|
|
|
if (!empty($d['MontoItem'])) { |
1047
|
|
|
$subtotal += $d['MontoItem']; |
1048
|
|
|
} |
1049
|
|
|
} |
1050
|
|
|
if ($this->papelContinuo) { |
1051
|
|
|
$this->Texto('Subtotal: '.$this->num($subtotal), $x); |
1052
|
|
|
} else { |
1053
|
|
|
$this->Texto('Subtotal:', 77, null, 'R', 100); |
1054
|
|
|
$this->Texto($this->num($subtotal), 177, null, 'R', 22); |
1055
|
|
|
} |
1056
|
|
|
$this->Ln(); |
1057
|
|
|
} |
1058
|
|
|
|
1059
|
|
|
/** |
1060
|
|
|
* Método que agrega los descuentos y/o recargos globales del documento |
1061
|
|
|
* @param descuentosRecargos Arreglo con los descuentos y/o recargos del documento (tag DscRcgGlobal del XML) |
1062
|
|
|
* @param x Posición horizontal de inicio en el PDF |
1063
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1064
|
|
|
* @version 2016-08-17 |
1065
|
|
|
*/ |
1066
|
|
|
protected function agregarDescuentosRecargos(array $descuentosRecargos, $x = 10) |
1067
|
|
|
{ |
1068
|
|
|
if (!isset($descuentosRecargos[0])) |
1069
|
|
|
$descuentosRecargos = [$descuentosRecargos]; |
1070
|
|
|
foreach($descuentosRecargos as $dr) { |
1071
|
|
|
$tipo = $dr['TpoMov']=='D' ? 'Descuento' : 'Recargo'; |
1072
|
|
|
$valor = $dr['TpoValor']=='%' ? $dr['ValorDR'].'%' : $this->num($dr['ValorDR']); |
1073
|
|
|
if ($this->papelContinuo) { |
1074
|
|
|
$this->Texto($tipo.' global: '.$valor.(!empty($dr['GlosaDR'])?(' ('.$dr['GlosaDR'].')'):''), $x); |
1075
|
|
|
} else { |
1076
|
|
|
$this->Texto($tipo.(!empty($dr['GlosaDR'])?(' ('.$dr['GlosaDR'].')'):'').':', 77, null, 'R', 100); |
1077
|
|
|
$this->Texto($valor, 177, null, 'R', 22); |
1078
|
|
|
} |
1079
|
|
|
$this->Ln(); |
1080
|
|
|
} |
1081
|
|
|
} |
1082
|
|
|
|
1083
|
|
|
/** |
1084
|
|
|
* Método que agrega los pagos del documento |
1085
|
|
|
* @param pagos Arreglo con los pagos del documento |
1086
|
|
|
* @param x Posición horizontal de inicio en el PDF |
1087
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1088
|
|
|
* @version 2016-07-24 |
1089
|
|
|
*/ |
1090
|
|
|
protected function agregarPagos(array $pagos, $x = 10) |
1091
|
|
|
{ |
1092
|
|
|
if (!isset($pagos[0])) |
1093
|
|
|
$pagos = [$pagos]; |
1094
|
|
|
$this->Texto('Pago(s) programado(s):', $x); |
1095
|
|
|
$this->Ln(); |
1096
|
|
|
foreach($pagos as $p) { |
1097
|
|
|
$this->Texto(' - '.$this->date($p['FchPago'], false).': $'.$this->num($p['MntPago']).'.-'.(!empty($p['GlosaPagos'])?(' ('.$p['GlosaPagos'].')'):''), $x); |
1098
|
|
|
$this->Ln(); |
1099
|
|
|
} |
1100
|
|
|
} |
1101
|
|
|
|
1102
|
|
|
/** |
1103
|
|
|
* Método que agrega los totales del documento |
1104
|
|
|
* @param totales Arreglo con los totales (tag Totales del XML) |
1105
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1106
|
|
|
* @version 2017-10-05 |
1107
|
|
|
*/ |
1108
|
|
|
protected function agregarTotales(array $totales, $otra_moneda, $y = 190, $x = 145, $offset = 25) |
1109
|
|
|
{ |
1110
|
|
|
$y = (!$this->papelContinuo and !$this->timbre_pie) ? $this->x_fin_datos : $y; |
|
|
|
|
1111
|
|
|
// normalizar totales |
1112
|
|
|
$totales = array_merge([ |
1113
|
|
|
'TpoMoneda' => false, |
1114
|
|
|
'MntNeto' => false, |
1115
|
|
|
'MntExe' => false, |
1116
|
|
|
'TasaIVA' => false, |
1117
|
|
|
'IVA' => false, |
1118
|
|
|
'IVANoRet' => false, |
1119
|
|
|
'CredEC' => false, |
1120
|
|
|
'MntTotal' => false, |
1121
|
|
|
'MontoNF' => false, |
1122
|
|
|
'MontoPeriodo' => false, |
1123
|
|
|
'SaldoAnterior' => false, |
1124
|
|
|
'VlrPagar' => false, |
1125
|
|
|
], $totales); |
1126
|
|
|
// glosas |
1127
|
|
|
$glosas = [ |
1128
|
|
|
'TpoMoneda' => 'Moneda', |
1129
|
|
|
'MntNeto' => 'Neto $', |
1130
|
|
|
'MntExe' => 'Exento $', |
1131
|
|
|
'IVA' => 'IVA ('.$totales['TasaIVA'].'%) $', |
1132
|
|
|
'IVANoRet' => 'IVA no retenido $', |
1133
|
|
|
'CredEC' => 'Desc. 65% IVA $', |
1134
|
|
|
'MntTotal' => 'Total $', |
1135
|
|
|
'MontoNF' => 'Monto no facturable $', |
1136
|
|
|
'MontoPeriodo' => 'Monto período $', |
1137
|
|
|
'SaldoAnterior' => 'Saldo anterior $', |
1138
|
|
|
'VlrPagar' => 'Valor a pagar $', |
1139
|
|
|
]; |
1140
|
|
|
// agregar impuestos adicionales y retenciones |
1141
|
|
|
if (!empty($totales['ImptoReten'])) { |
1142
|
|
|
$ImptoReten = $totales['ImptoReten']; |
1143
|
|
|
$MntTotal = $totales['MntTotal']; |
1144
|
|
|
unset($totales['ImptoReten'], $totales['MntTotal']); |
1145
|
|
|
if (!isset($ImptoReten[0])) { |
1146
|
|
|
$ImptoReten = [$ImptoReten]; |
1147
|
|
|
} |
1148
|
|
|
foreach($ImptoReten as $i) { |
1149
|
|
|
$totales['ImptoReten_'.$i['TipoImp']] = $i['MontoImp']; |
1150
|
|
|
if (!empty($i['TasaImp'])) { |
1151
|
|
|
$glosas['ImptoReten_'.$i['TipoImp']] = \sasco\LibreDTE\Sii\ImpuestosAdicionales::getGlosa($i['TipoImp']).' ('.$i['TasaImp'].'%) $'; |
1152
|
|
|
} else { |
1153
|
|
|
$glosas['ImptoReten_'.$i['TipoImp']] = \sasco\LibreDTE\Sii\ImpuestosAdicionales::getGlosa($i['TipoImp']).' $'; |
1154
|
|
|
} |
1155
|
|
|
} |
1156
|
|
|
$totales['MntTotal'] = $MntTotal; |
1157
|
|
|
} |
1158
|
|
|
// agregar cada uno de los totales |
1159
|
|
|
$this->setY($y); |
1160
|
|
|
$this->setFont('', 'B', null); |
1161
|
|
|
foreach ($totales as $key => $total) { |
1162
|
|
|
if ($total!==false and isset($glosas[$key])) { |
|
|
|
|
1163
|
|
|
$y = $this->GetY(); |
1164
|
|
|
if (!$this->cedible or $this->papelContinuo) { |
|
|
|
|
1165
|
|
|
$this->Texto($glosas[$key].' :', $x, null, 'R', 30); |
1166
|
|
|
$this->Texto($this->num($total), $x+$offset, $y, 'R', 30); |
1167
|
|
|
$this->Ln(); |
1168
|
|
|
} else { |
1169
|
|
|
$this->MultiTexto($glosas[$key].' :', $x, null, 'R', 30); |
1170
|
|
|
$y_new = $this->GetY(); |
1171
|
|
|
$this->Texto($this->num($total), $x+$offset, $y, 'R', 30); |
1172
|
|
|
$this->SetY($y_new); |
1173
|
|
|
} |
1174
|
|
|
} |
1175
|
|
|
} |
1176
|
|
|
// agregar totales en otra moneda |
1177
|
|
|
if (!empty($otra_moneda)) { |
1178
|
|
|
if (!isset($otra_moneda[0])) { |
1179
|
|
|
$otra_moneda = [$otra_moneda]; |
1180
|
|
|
} |
1181
|
|
|
$this->setFont('', '', null); |
1182
|
|
|
$this->Ln(); |
1183
|
|
|
foreach ($otra_moneda as $om) { |
1184
|
|
|
$y = $this->GetY(); |
1185
|
|
|
if (!$this->cedible or $this->papelContinuo) { |
|
|
|
|
1186
|
|
|
$this->Texto('Total '.$om['TpoMoneda'].' :', $x, null, 'R', 30); |
1187
|
|
|
$this->Texto($this->num($om['MntTotOtrMnda']), $x+$offset, $y, 'R', 30); |
1188
|
|
|
$this->Ln(); |
1189
|
|
|
} else { |
1190
|
|
|
$this->MultiTexto('Total '.$om['TpoMoneda'].' :', $x, null, 'R', 30); |
1191
|
|
|
$y_new = $this->GetY(); |
1192
|
|
|
$this->Texto($this->num($om['MntTotOtrMnda']), $x+$offset, $y, 'R', 30); |
1193
|
|
|
$this->SetY($y_new); |
1194
|
|
|
} |
1195
|
|
|
} |
1196
|
|
|
$this->setFont('', 'B', null); |
1197
|
|
|
} |
1198
|
|
|
} |
1199
|
|
|
|
1200
|
|
|
/** |
1201
|
|
|
* Método que coloca las diferentes observaciones que puede tener el documnto |
1202
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1203
|
|
|
* @version 2018-01-26 |
1204
|
|
|
*/ |
1205
|
|
|
protected function agregarObservacion($IdDoc, $x = 10, $y = 190) |
1206
|
|
|
{ |
1207
|
|
|
$y = (!$this->papelContinuo and !$this->timbre_pie) ? $this->x_fin_datos : $y; |
|
|
|
|
1208
|
|
|
if (!$this->papelContinuo and $this->timbre_pie) { |
|
|
|
|
1209
|
|
|
$y -= 15; |
1210
|
|
|
} |
1211
|
|
|
$this->SetXY($x, $y); |
1212
|
|
|
if (!empty($IdDoc['TermPagoGlosa'])) { |
1213
|
|
|
$this->MultiTexto('Observación: '.$IdDoc['TermPagoGlosa']); |
1214
|
|
|
} |
1215
|
|
|
if (!empty($IdDoc['MedioPago']) or !empty($IdDoc['TermPagoDias'])) { |
|
|
|
|
1216
|
|
|
$pago = []; |
1217
|
|
|
if (!empty($IdDoc['MedioPago'])) { |
1218
|
|
|
$medio = !empty($this->medios_pago[$IdDoc['MedioPago']]) ? $this->medios_pago[$IdDoc['MedioPago']] : $IdDoc['MedioPago']; |
1219
|
|
|
$pago[] = 'Medio de pago: '.$medio; |
1220
|
|
|
} |
1221
|
|
|
if (!empty($IdDoc['TermPagoDias'])) { |
1222
|
|
|
$pago[] = 'Días de pago: '.$IdDoc['TermPagoDias']; |
1223
|
|
|
} |
1224
|
|
|
$this->SetXY($x, $this->GetY()); |
1225
|
|
|
$this->MultiTexto(implode(' / ', $pago)); |
1226
|
|
|
} |
1227
|
|
|
return $this->GetY(); |
1228
|
|
|
} |
1229
|
|
|
|
1230
|
|
|
/** |
1231
|
|
|
* Método que agrega el timbre de la factura |
1232
|
|
|
* - Se imprime en el tamaño mínimo: 2x5 cms |
1233
|
|
|
* - En el lado de abajo con margen izquierdo mínimo de 2 cms |
1234
|
|
|
* @param timbre String con los datos del timbre |
1235
|
|
|
* @param x Posición horizontal de inicio en el PDF |
1236
|
|
|
* @param y Posición vertical de inicio en el PDF |
1237
|
|
|
* @param w Ancho del timbre |
1238
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1239
|
|
|
* @version 2018-04-12 |
1240
|
|
|
*/ |
1241
|
|
|
protected function agregarTimbre($timbre, $x_timbre = 10, $x = 10, $y = 190, $w = 70, $font_size = 8) |
1242
|
|
|
{ |
1243
|
|
|
$y = (!$this->papelContinuo and !$this->timbre_pie) ? $this->x_fin_datos : $y; |
|
|
|
|
1244
|
|
|
if ($timbre!==null) { |
1245
|
|
|
$style = [ |
1246
|
|
|
'border' => false, |
1247
|
|
|
'padding' => 0, |
1248
|
|
|
'hpadding' => 0, |
1249
|
|
|
'vpadding' => 0, |
1250
|
|
|
'module_width' => 1, // width of a single module in points |
1251
|
|
|
'module_height' => 1, // height of a single module in points |
1252
|
|
|
'fgcolor' => [0,0,0], |
1253
|
|
|
'bgcolor' => false, // [255,255,255] |
|
|
|
|
1254
|
|
|
'position' => $this->papelContinuo ? 'C' : 'S', |
1255
|
|
|
]; |
1256
|
|
|
$ecl = version_compare(phpversion(), '7.0.0', '<') ? -1 : $this->ecl; |
1257
|
|
|
$this->write2DBarcode($timbre, 'PDF417,,'.$ecl, $x_timbre, $y, $w, 0, $style, 'B'); |
1258
|
|
|
$this->setFont('', 'B', $font_size); |
1259
|
|
|
$this->Texto('Timbre Electrónico SII', $x, null, 'C', $w); |
1260
|
|
|
$this->Ln(); |
1261
|
|
|
$this->Texto('Resolución '.$this->resolucion['NroResol'].' de '.explode('-', $this->resolucion['FchResol'])[0], $x, null, 'C', $w); |
1262
|
|
|
$this->Ln(); |
1263
|
|
|
if ($w>=60) { |
1264
|
|
|
$this->Texto('Verifique documento: '.$this->web_verificacion, $x, null, 'C', $w); |
1265
|
|
|
} else { |
1266
|
|
|
$this->Texto('Verifique documento:', $x, null, 'C', $w); |
1267
|
|
|
$this->Ln(); |
1268
|
|
|
$this->Texto($this->web_verificacion, $x, null, 'C', $w); |
1269
|
|
|
} |
1270
|
|
|
} |
1271
|
|
|
} |
1272
|
|
|
|
1273
|
|
|
/** |
1274
|
|
|
* Método que agrega el acuse de rebido |
1275
|
|
|
* @param x Posición horizontal de inicio en el PDF |
1276
|
|
|
* @param y Posición vertical de inicio en el PDF |
1277
|
|
|
* @param w Ancho del acuse de recibo |
1278
|
|
|
* @param h Alto del acuse de recibo |
1279
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1280
|
|
|
* @version 2018-04-13 |
1281
|
|
|
*/ |
1282
|
|
|
protected function agregarAcuseRecibo($x = 83, $y = 190, $w = 60, $h = 40) |
1283
|
|
|
{ |
1284
|
|
|
$y = (!$this->papelContinuo and !$this->timbre_pie) ? $this->x_fin_datos : $y; |
|
|
|
|
1285
|
|
|
$this->SetTextColorArray([0,0,0]); |
1286
|
|
|
$this->Rect($x, $y, $w, $h, 'D', ['all' => ['width' => 0.1, 'color' => [0, 0, 0]]]); |
1287
|
|
|
$this->setFont('', 'B', 10); |
1288
|
|
|
$this->Texto('Acuse de recibo', $x, $y+1, 'C', $w); |
1289
|
|
|
$this->setFont('', 'B', 8); |
1290
|
|
|
$this->Texto('Nombre', $x+2, $this->y+8); |
1291
|
|
|
$this->Texto('_________________________', $x+18); |
1292
|
|
|
$this->Texto('RUN', $x+2, $this->y+6); |
1293
|
|
|
$this->Texto('_________________________', $x+18); |
1294
|
|
|
$this->Texto('Fecha', $x+2, $this->y+6); |
1295
|
|
|
$this->Texto('_________________________', $x+18); |
1296
|
|
|
$this->Texto('Recinto', $x+2, $this->y+6); |
1297
|
|
|
$this->Texto('_________________________', $x+18); |
1298
|
|
|
$this->Texto('Firma', $x+2, $this->y+8); |
1299
|
|
|
$this->Texto('_________________________', $x+18); |
1300
|
|
|
$this->setFont('', 'B', 7); |
1301
|
|
|
$this->MultiTexto('El acuse de recibo que se declara en este acto, de acuerdo a lo dispuesto en la letra b) del Art. 4°, y la letra c) del Art. 5° de la Ley 19.983, acredita que la entrega de mercaderías o servicio (s) prestado (s) ha (n) sido recibido (s).'."\n", $x, $this->y+6, 'J', $w); |
1302
|
|
|
} |
1303
|
|
|
|
1304
|
|
|
/** |
1305
|
|
|
* Método que agrega el acuse de rebido |
1306
|
|
|
* @param x Posición horizontal de inicio en el PDF |
1307
|
|
|
* @param y Posición vertical de inicio en el PDF |
1308
|
|
|
* @param w Ancho del acuse de recibo |
1309
|
|
|
* @param h Alto del acuse de recibo |
1310
|
|
|
* @author Pablo Reyes (https://github.com/pabloxp) |
1311
|
|
|
* @version 2015-11-17 |
1312
|
|
|
*/ |
1313
|
|
|
protected function agregarAcuseReciboContinuo($x = 3, $y = null, $w = 68, $h = 40) |
1314
|
|
|
{ |
1315
|
|
|
$this->SetTextColorArray([0,0,0]); |
1316
|
|
|
$this->Rect($x, $y, $w, $h, 'D', ['all' => ['width' => 0.1, 'color' => [0, 0, 0]]]); |
1317
|
|
|
$style = array('width' => 0.2,'color' => array(0, 0, 0)); |
1318
|
|
|
$this->Line($x, $y+22, $w+3, $y+22, $style); |
1319
|
|
|
//$this->setFont('', 'B', 10); |
|
|
|
|
1320
|
|
|
//$this->Texto('Acuse de recibo', $x, $y+1, 'C', $w); |
|
|
|
|
1321
|
|
|
$this->setFont('', 'B', 6); |
1322
|
|
|
$this->Texto('Nombre', $x+2, $this->y+8); |
1323
|
|
|
$this->Texto('_____________________________________________', $x+12); |
1324
|
|
|
$this->Texto('RUN', $x+2, $this->y+6); |
1325
|
|
|
$this->Texto('________________', $x+12); |
1326
|
|
|
$this->Texto('Firma', $x+32, $this->y+0.5); |
1327
|
|
|
$this->Texto('___________________', $x+42.5); |
1328
|
|
|
$this->Texto('Fecha', $x+2, $this->y+6); |
1329
|
|
|
$this->Texto('________________', $x+12); |
1330
|
|
|
$this->Texto('Recinto', $x+32, $this->y+0.5); |
1331
|
|
|
$this->Texto('___________________', $x+42.5); |
1332
|
|
|
|
1333
|
|
|
$this->setFont('', 'B', 5); |
1334
|
|
|
$this->MultiTexto('El acuse de recibo que se declara en este acto, de acuerdo a lo dispuesto en la letra b) del Art. 4°, y la letra c) del Art. 5° de la Ley 19.983, acredita que la entrega de mercaderías o servicio (s) prestado (s) ha (n) sido recibido (s).'."\n", $x+2, $this->y+8, 'J', $w-3); |
1335
|
|
|
} |
1336
|
|
|
|
1337
|
|
|
/** |
1338
|
|
|
* Método que agrega la leyenda de destino |
1339
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1340
|
|
|
* @version 2017-10-05 |
1341
|
|
|
*/ |
1342
|
|
|
protected function agregarLeyendaDestino($tipo, $y = 190, $font_size = 10) |
1343
|
|
|
{ |
1344
|
|
|
$y = (!$this->papelContinuo and !$this->timbre_pie) ? $this->x_fin_datos : $y; |
|
|
|
|
1345
|
|
|
$y += 64; |
1346
|
|
|
$this->setFont('', 'B', $font_size); |
1347
|
|
|
$this->Texto('CEDIBLE'.($tipo==52?' CON SU FACTURA':''), null, $y, 'R'); |
1348
|
|
|
} |
1349
|
|
|
|
1350
|
|
|
/** |
1351
|
|
|
* Método que agrega la leyenda de destino |
1352
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1353
|
|
|
* @version 2017-10-05 |
1354
|
|
|
*/ |
1355
|
|
|
protected function agregarLeyendaDestinoContinuo($tipo) |
1356
|
|
|
{ |
1357
|
|
|
$this->setFont('', 'B', 8); |
1358
|
|
|
$this->Texto('CEDIBLE'.($tipo==52?' CON SU FACTURA':''), null, $this->y+6, 'R'); |
1359
|
|
|
} |
1360
|
|
|
|
1361
|
|
|
/** |
1362
|
|
|
* Método que formatea un número con separador de miles y decimales (si |
1363
|
|
|
* corresponden) |
1364
|
|
|
* @param n Número que se desea formatear |
1365
|
|
|
* @return Número formateado |
1366
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1367
|
|
|
* @version 2016-04-05 |
1368
|
|
|
*/ |
1369
|
|
|
protected function num($n) |
1370
|
|
|
{ |
1371
|
|
|
if (!is_numeric($n)) |
1372
|
|
|
return $n; |
1373
|
|
|
$broken_number = explode('.', (string)$n); |
1374
|
|
|
if (isset($broken_number[1])) |
1375
|
|
|
return number_format($broken_number[0], 0, ',', '.').','.$broken_number[1]; |
|
|
|
|
1376
|
|
|
return number_format($broken_number[0], 0, ',', '.'); |
|
|
|
|
1377
|
|
|
} |
1378
|
|
|
|
1379
|
|
|
/** |
1380
|
|
|
* Método que formatea una fecha en formato YYYY-MM-DD a un string |
1381
|
|
|
* @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
1382
|
|
|
* @version 2016-04-28 |
1383
|
|
|
*/ |
1384
|
|
|
protected function date($date, $mostrar_dia = true) |
1385
|
|
|
{ |
1386
|
|
|
$dias = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado']; |
1387
|
|
|
$meses = ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre']; |
1388
|
|
|
$unixtime = strtotime($date); |
1389
|
|
|
$fecha = date(($mostrar_dia?'\D\I\A ':'').'j \d\e \M\E\S \d\e\l Y', $unixtime); |
1390
|
|
|
$dia = $dias[date('w', $unixtime)]; |
1391
|
|
|
$mes = $meses[date('n', $unixtime)-1]; |
1392
|
|
|
return str_replace(array('DIA', 'MES'), array($dia, $mes), $fecha); |
1393
|
|
|
} |
1394
|
|
|
|
1395
|
|
|
} |
1396
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.