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