informe_facturas   F
last analyzed

Complexity

Total Complexity 144

Size/Duplication

Total Lines 1027
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 661
c 2
b 0
f 0
dl 0
loc 1027
rs 1.939
wmc 144

21 Methods

Rating   Name   Duplication   Size   Complexity  
A process_lineas_iva() 0 17 3
C desglose_impuestos_pdf() 0 71 12
A generar_extra() 0 13 5
A stats_almacenes() 0 3 1
A stats_formas_pago() 0 3 1
B stats_estados() 0 36 6
A private_core() 0 12 1
A __construct() 0 3 1
B get_documentos() 0 41 7
A provincias() 0 3 1
A stats_agentes() 0 3 1
A stats_series() 0 3 1
F informe_compras() 0 110 19
C generar_pdf() 0 158 13
A generar_csv() 0 48 4
F informe_ventas() 0 121 23
F informe_compras_unidades() 0 100 17
A set_where() 0 8 3
F informe_ventas_unidades() 0 110 19
A ini_filters() 0 7 2
B generar_xls() 0 80 4

How to fix   Complexity   

Complex Class

Complex classes like informe_facturas often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use informe_facturas, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * This file is part of facturacion_base
4
 * Copyright (C) 2013-2020  Carlos Garcia Gomez     <[email protected]>
5
 * Copyright (C) 2017       Francesc Pineda Segarra <francesc.pì[email protected]>
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
require_once 'plugins/republica_dominicana/controller/informe_albaranes.php';
21
22
/**
23
 * Heredamos del controlador de informe_albaranes, para reaprovechar el código.
24
 */
25
class informe_facturas extends informe_albaranes
26
{
27
    public $pais;
28
    public $estado;
29
    public $nombre_docs;
30
    public $table_compras;
31
    public $table_ventas;
32
    public function __construct()
33
    {
34
        parent::__construct(__CLASS__, 'Facturas', 'informes');
0 ignored issues
show
Bug introduced by
__CLASS__ of type string is incompatible with the type system expected by parameter $name of informe_albaranes::__construct(). ( Ignorable by Annotation )

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

34
        parent::__construct(/** @scrutinizer ignore-type */ __CLASS__, 'Facturas', 'informes');
Loading history...
Bug introduced by
'Facturas' of type string is incompatible with the type type expected by parameter $title of informe_albaranes::__construct(). ( Ignorable by Annotation )

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

34
        parent::__construct(__CLASS__, /** @scrutinizer ignore-type */ 'Facturas', 'informes');
Loading history...
35
    }
36
37
    protected function private_core()
38
    {
39
        /// declaramos los objetos sólo para asegurarnos de que existen las tablas
40
        new factura_cliente();
41
        new factura_proveedor();
42
43
        $this->nombre_docs = 'Facturas';
44
        $this->pais = new pais();
0 ignored issues
show
Bug introduced by
The type pais was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
45
        $this->table_compras = 'facturasprov';
46
        $this->table_ventas = 'facturascli';
47
48
        parent::private_core();
49
    }
50
51
    protected function generar_extra()
52
    {
53
        if ($_POST['generar'] === 'informe_compras') {
54
            if ($_POST['unidades'] === 'TRUE') {
55
                $this->informe_compras_unidades();
56
            } else {
57
                $this->informe_compras();
58
            }
59
        } elseif ($_POST['generar'] === 'informe_ventas') {
60
            if ($_POST['unidades'] === 'TRUE') {
61
                $this->informe_ventas_unidades();
62
            } else {
63
                $this->informe_ventas();
64
            }
65
        }
66
    }
67
68
    public function provincias()
69
    {
70
        return $this->fbase_sql_distinct('dirclientes', 'provincia');
71
    }
72
73
    public function stats_series($tabla = 'facturasprov')
74
    {
75
        return parent::stats_series($tabla);
76
    }
77
78
    /**
79
     * @param $tabla
80
     * @return array
81
     */
82
    public function stats_agentes($tabla = 'facturasprov')
83
    {
84
        return parent::stats_agentes($tabla);
85
    }
86
87
    public function stats_almacenes($tabla = 'facturasprov')
88
    {
89
        return parent::stats_almacenes($tabla);
90
    }
91
92
    public function stats_formas_pago($tabla = 'facturasprov')
93
    {
94
        return parent::stats_formas_pago($tabla);
95
    }
96
97
    public function stats_estados($tabla = 'facturasprov')
98
    {
99
        $stats = array();
100
101
        $where = $this->where_compras;
102
        if ($tabla === $this->table_ventas) {
103
            $where = $this->where_ventas;
104
        }
105
106
        /// aprobados
107
        $sql = "select sum(neto) as total from " . $tabla;
108
        $sql .= $where;
109
        $sql .= " and idfactura is not null and anulada = false order by total desc;";
110
111
        $data = $this->db->select($sql);
112
        if ($data && (float)$data[0]['total']) {
113
            $stats[] = array(
114
                'txt' => 'facturado',
115
                'total' => round((float)$data[0]['total'], FS_NF0)
116
            );
117
        }
118
119
        /// pendientes
120
        $sql = "select sum(neto) as total from " . $tabla;
121
        $sql .= $where;
122
        $sql .= " and idfactura is null and anulada = false order by total desc;";
123
124
        $data = $this->db->select($sql);
125
        if ($data && (float)$data[0]['total']) {
126
            $stats[] = array(
127
                'txt' => 'no facturado',
128
                'total' => round((float)$data[0]['total'], FS_NF0)
129
            );
130
        }
131
132
        return $stats;
133
    }
134
135
    protected function get_documentos($tabla)
136
    {
137
        $doclist = array();
138
139
        $where = $this->where_compras;
140
        if ($tabla === $this->table_ventas) {
141
            $where = $this->where_ventas;
142
        }
143
144
        $sql = "select * from " . $tabla . $where . " order by fecha asc, codigo asc;";
145
        $data = $this->db->select($sql);
146
        if ($data) {
147
            foreach ($data as $d) {
148
                if ($tabla === $this->table_ventas) {
149
                    $sql = "SELECT * FROM lineasivafactcli WHERE idfactura = " .
150
                        $this->empresa->var2str($d['idfactura']) . " ORDER BY iva DESC";
151
                    $dataiva = $this->db->select($sql);
152
                    if ($dataiva) {
153
                        $this->process_lineas_iva($doclist, $dataiva, $d, 'factura_cliente');
154
                    } else {
155
                        $factura = new factura_cliente($d);
156
                        $factura->tasaiva = 0;
157
                        $factura->tasare = 0;
158
                        $doclist[] = $factura;
159
                    }
160
                } else {
161
                    $sql = "SELECT * FROM lineasivafactprov WHERE idfactura = " .
162
                        $this->empresa->var2str($d['idfactura']) . " ORDER BY iva DESC";
163
                    $dataiva = $this->db->select($sql);
164
                    if ($dataiva) {
165
                        $this->process_lineas_iva($doclist, $dataiva, $d, 'factura_proveedor');
166
                    } else {
167
                        $factura = new factura_proveedor($d);
168
                        $factura->tasaiva = 0;
169
                        $factura->tasare = 0;
170
                        $doclist[] = $factura;
171
                    }
172
                }
173
            }
174
        }
175
        return $doclist;
176
    }
177
178
    /**
179
     * A partir de los datos de lineasivafactcli (o prov) completamos el listado
180
     * de facturas desglosando por tipo de iva.
181
     * @param array $docList
182
     * @param array $dataIVA
183
     * @param array $dataFactura
184
     * @param string $className
185
     */
186
    private function process_lineas_iva(&$docList, &$dataIVA, &$dataFactura, $className)
187
    {
188
        foreach ($dataIVA as $key => $diva) {
189
            $dataFactura['neto'] = $diva['neto'];
190
            $dataFactura['totaliva'] = $diva['totaliva'];
191
            $dataFactura['totalrecargo'] = $diva['totalrecargo'];
192
            if ($key !== 0) {
193
                $dataFactura['irpf'] = 0;
194
                $dataFactura['totalirpf'] = 0;
195
            }
196
            $dataFactura['total'] =
197
                $diva['neto'] + $dataFactura['totaliva'] + $dataFactura['totalrecargo'] - $dataFactura['totalirpf'];
198
199
            $factura = new $className($dataFactura);
200
            $factura->tasaiva = $diva['iva'];
201
            $factura->tasare = $diva['recargo'];
202
            $docList[] = $factura;
203
        }
204
    }
205
206
    /**
207
     * Añade el desglose de impuestos al documento PDF.
208
     * @param fs_pdf $pdf_doc
209
     * @param string $tipo
210
     */
211
    protected function desglose_impuestos_pdf(&$pdf_doc, $tipo)
212
    {
213
        $impuestos = array();
214
        if ($tipo === 'compra' && $this->db->table_exists('lineasivafactprov')) {
215
            $sql = "select * from lineasivafactprov WHERE idfactura IN"
216
                . " (select idfactura from facturasprov " . $this->where_compras . ")"
217
                . " order by iva asc;";
218
        } elseif ($tipo === 'venta' && $this->db->table_exists('lineasivafactcli')) {
219
            $sql = "select * from lineasivafactcli WHERE idfactura IN"
220
                . " (select idfactura from facturascli " . $this->where_ventas . ")"
221
                . " order by iva asc;";
222
        } else {
223
            return false;
224
        }
225
226
        $data = $this->db->select($sql);
227
        if ($data) {
228
            foreach ($data as $d) {
229
                if ($tipo === 'compra') {
230
                    $liva = new linea_iva_factura_proveedor($d);
231
                } else {
232
                    $liva = new linea_iva_factura_cliente($d);
233
                }
234
235
                /**
236
                 * Debemos fiarnos de que los cálculos de las líneas de iva sean correctos.
237
                 * Si hubiese un error, es en la generación de las lineas de iva donde hay
238
                 * que solucionarlo.
239
                 */
240
                if (isset($impuestos['iva'][$liva->iva])) {
241
                    $impuestos['iva'][$liva->iva]['base'] += $liva->neto;
242
                    $impuestos['iva'][$liva->iva]['totaliva'] += $liva->totaliva;
243
                    $impuestos['iva'][$liva->iva]['totalre'] += $liva->totalrecargo;
244
                } else {
245
                    $impuestos['iva'][$liva->iva]['base'] = $liva->neto;
246
                    $impuestos['iva'][$liva->iva]['totaliva'] = $liva->totaliva;
247
                    $impuestos['iva'][$liva->iva]['totalre'] = $liva->totalrecargo;
248
                }
249
            }
250
        }
251
252
        if (!empty($impuestos)) {
253
            $header = array();
254
            $row = array();
255
256
            foreach ($impuestos['iva'] as $key => $value) {
257
                $header[] = 'Base ' . $key . '%';
258
                $row[] = $this->show_numero($value['base']);
259
260
                $header[] = FS_IVA . ' ' . $key . '%';
261
                $row[] = $this->show_numero($value['totaliva']);
262
263
                if ($value['totalre']) {
264
                    $header[] = 'RE ' . $key . '%';
265
                    $row[] = $this->show_numero($value['totalre']);
266
                }
267
            }
268
269
            $pdf_doc->pdf->ezText("\n");
270
            $pdf_doc->new_table();
271
            $pdf_doc->add_table_header($header);
272
            $pdf_doc->add_table_row($row);
273
            $pdf_doc->save_table(
274
                array(
275
                    'fontSize' => 8,
276
                    'shaded' => 0,
277
                    'width' => 780
278
                )
279
            );
280
        } else {
281
            $pdf_doc->pdf->ezText("\nSin impuestos.");
282
        }
283
    }
284
285
    /**
286
     * @return void
287
     */
288
    private function informe_compras()
289
    {
290
        $sql = "SELECT codproveedor,fecha,SUM(neto) as total FROM facturasprov"
291
            . " WHERE fecha >= " . $this->empresa->var2str($this->desde)
292
            . " AND anulada = false "
293
            . " AND fecha <= " . $this->empresa->var2str($this->hasta);
294
295
        if ($this->codserie) {
296
            $sql .= " AND codserie = " . $this->empresa->var2str($this->codserie);
297
        }
298
299
        if ($this->codagente) {
300
            $sql .= " AND codagente = " . $this->empresa->var2str($this->codagente);
301
        }
302
303
        if ($this->proveedor) {
304
            $sql .= " AND codproveedor = " . $this->empresa->var2str($this->proveedor->codproveedor);
305
        }
306
307
        if ($_POST['minimo']) {
308
            $sql .= " AND neto > " . $this->empresa->var2str($_POST['minimo']);
309
        }
310
311
        $sql .= " GROUP BY codproveedor,fecha ORDER BY codproveedor ASC, fecha DESC;";
312
313
        $data = $this->db->select($sql);
314
        if ($data) {
315
            $this->template = false;
316
            header("content-type:application/csv;charset=UTF-8");
317
            header("Content-Disposition: attachment; filename=\"informe_compras.csv\"");
318
            echo "codproveedor;nombre;año;ene;feb;mar;abr;may;jun;jul;ago;sep;oct;nov;dic;total;%VAR\n";
319
320
            $proveedor = new proveedor();
321
            $stats = array();
322
            foreach ($data as $d) {
323
                $anyo = date('Y', strtotime($d['fecha']));
324
                $mes = date('n', strtotime($d['fecha']));
325
                if (!isset($stats[$d['codproveedor']][$anyo])) {
326
                    $stats[$d['codproveedor']][$anyo] = array(
327
                        1 => 0,
328
                        2 => 0,
329
                        3 => 0,
330
                        4 => 0,
331
                        5 => 0,
332
                        6 => 0,
333
                        7 => 0,
334
                        8 => 0,
335
                        9 => 0,
336
                        10 => 0,
337
                        11 => 0,
338
                        12 => 0,
339
                        13 => 0,
340
                        14 => 0
341
                    );
342
                }
343
344
                $stats[$d['codproveedor']][$anyo][$mes] += (float)$d['total'];
345
                $stats[$d['codproveedor']][$anyo][13] += (float)$d['total'];
346
            }
347
348
            $totales = array();
349
            foreach ($stats as $i => $value) {
350
                /// calculamos la variación
351
                $anterior = 0;
352
                foreach (array_reverse($value, true) as $j => $value2) {
353
                    if ($anterior > 0) {
354
                        $value[$j][14] = ($value2[13] * 100 / $anterior) - 100;
355
                    }
356
357
                    $anterior = $value2[13];
358
359
                    if (isset($totales[$j])) {
360
                        foreach ($value2 as $k => $value3) {
361
                            $totales[$j][$k] += $value3;
362
                        }
363
                    } else {
364
                        $totales[$j] = $value2;
365
                    }
366
                }
367
368
                $pro = $proveedor->get($i);
369
                foreach ($value as $j => $value2) {
370
                    if ($pro) {
371
                        echo '"' . $i . '";' . fs_fix_html($pro->nombre) . ';' . $j;
372
                    } else {
373
                        echo '"' . $i . '";-;' . $j;
374
                    }
375
376
                    foreach ($value2 as $value3) {
377
                        echo ';' . number_format($value3, FS_NF0, FS_NF1, FS_NF2);
378
                    }
379
380
                    echo "\n";
381
                }
382
                echo ";;;;;;;;;;;;;;;\n";
383
            }
384
385
            foreach (array_reverse($totales, true) as $i => $value) {
386
                echo ";TOTALES;" . $i;
387
                $l_total = 0;
388
                foreach ($value as $j => $value3) {
389
                    if ($j < 13) {
390
                        echo ';' . number_format($value3, FS_NF0, FS_NF1, FS_NF2);
391
                        $l_total += $value3;
392
                    }
393
                }
394
                echo ";" . number_format($l_total, FS_NF0, FS_NF1, FS_NF2) . ";\n";
395
            }
396
        } else {
397
            $this->new_error_msg('Sin resultados.');
398
        }
399
    }
400
401
    private function informe_ventas()
402
    {
403
        $sql = "SELECT codalmacen,codcliente,fecha,SUM(neto) as total FROM facturascli"
404
            . " WHERE fecha >= " . $this->empresa->var2str($this->desde)
405
            . " AND anulada = false "
406
            . " AND fecha <= " . $this->empresa->var2str($this->hasta);
407
408
        if ($_POST['codpais']) {
409
            $sql .= " AND codpais = " . $this->empresa->var2str($_POST['codpais']);
410
        }
411
412
        if ($_POST['provincia']) {
413
            $sql .= " AND lower(provincia) = lower(" . $this->empresa->var2str($_POST['provincia']) . ")";
414
        }
415
416
        if ($this->cliente) {
417
            $sql .= " AND codcliente = " . $this->empresa->var2str($this->cliente->codcliente);
418
        }
419
420
        if ($this->codserie) {
421
            $sql .= " AND codserie = " . $this->empresa->var2str($this->codserie);
422
        }
423
424
        if ($this->codalmacen) {
425
            $sql .= " AND codalmacen = " . $this->empresa->var2str($this->codalmacen);
426
        }
427
428
        if ($this->codagente) {
429
            $sql .= " AND codagente = " . $this->empresa->var2str($this->codagente);
430
        }
431
432
        if ($_POST['minimo']) {
433
            $sql .= " AND neto > " . $this->empresa->var2str($_POST['minimo']);
434
        }
435
436
        $sql .= " GROUP BY codalmacen,codcliente,fecha ORDER BY codcliente ASC, fecha DESC;";
437
438
        $data = $this->db->select($sql);
439
        if ($data) {
440
            $this->template = FALSE;
441
            header("content-type:application/csv;charset=UTF-8");
442
            header("Content-Disposition: attachment; filename=\"informe_ventas.csv\"");
443
            echo "almacen;codcliente;nombre;año;ene;feb;mar;abr;may;jun;jul;ago;sep;oct;nov;dic;total;%VAR\n";
444
            $cliente = new cliente();
0 ignored issues
show
Bug introduced by
The type cliente was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
445
            $stats = array();
446
            foreach ($data as $d) {
447
                $anyo = date('Y', strtotime($d['fecha']));
448
                $mes = date('n', strtotime($d['fecha']));
449
                if (!isset($stats[$d['codcliente']][$anyo])) {
450
                    $stats[$d['codcliente']][$anyo] = [
451
                        1 => 0,
452
                        2 => 0,
453
                        3 => 0,
454
                        4 => 0,
455
                        5 => 0,
456
                        6 => 0,
457
                        7 => 0,
458
                        8 => 0,
459
                        9 => 0,
460
                        10 => 0,
461
                        11 => 0,
462
                        12 => 0,
463
                        13 => 0,
464
                        14 => 0,
465
                        15 => $d['codalmacen']
466
                    ];
467
                }
468
469
                $stats[$d['codcliente']][$anyo][$mes] += (float)$d['total'];
470
                $stats[$d['codcliente']][$anyo][13] += (float)$d['total'];
471
            }
472
473
            $totales = array();
474
            foreach ($stats as $i => $value) {
475
                /// calculamos la variación y los totales
476
                $anterior = 0;
477
                foreach (array_reverse($value, true) as $j => $value2) {
478
                    if ($anterior > 0) {
479
                        $value[$j][14] = ($value2[13] * 100 / $anterior) - 100;
480
                    }
481
482
                    $anterior = $value2[13];
483
484
                    if (isset($totales[$j])) {
485
                        foreach ($value2 as $k => $value3) {
486
                            $totales[$j][$k] += $value3;
487
                        }
488
                    } else {
489
                        $totales[$j] = $value2;
490
                    }
491
                }
492
493
                $cli = $cliente->get($i);
494
                foreach ($value as $j => $value2) {
495
                    if ($cli) {
496
                        echo '"' . $value[$j][15] . '";' . '"' . $i . '";' . fs_fix_html($cli->nombre) . ';' . $j;
497
                    } else {
498
                        echo '"' . $value[$j][15] . '";' . '"' . $i . '";-;' . $j;
499
                    }
500
501
                    foreach ($value2 as $x => $value3) {
502
                        if ($x < 15) {
503
                            echo ';' . $this->show_numero($value3, FS_NF0);
504
                        }
505
                    }
506
                    echo "\n";
507
                }
508
                echo ";;;;;;;;;;;;;;;\n";
509
            }
510
            foreach (array_reverse($totales, true) as $i => $value) {
511
                echo ";TOTALES;" . $i;
512
                $l_total = 0;
513
                foreach ($value as $j => $value3) {
514
                    if ($j < 13) {
515
                        echo ';' . $this->show_numero($value3, FS_NF0);
516
                    }
517
                }
518
                echo ";" . $this->show_numero($l_total, FS_NF0) . ";\n";
519
            }
520
        } else {
521
            $this->new_error_msg('Sin resultados.');
522
        }
523
    }
524
525
    private function informe_compras_unidades()
526
    {
527
        $sql = "SELECT f.codalmacen,f.codproveedor,f.fecha,l.referencia,l.descripcion,SUM(l.cantidad) as total"
528
            . " FROM facturasprov f, lineasfacturasprov l"
529
            . " WHERE f.idfactura = l.idfactura AND l.referencia IS NOT NULL AND anulada = false "
530
            . " AND f.fecha >= " . $this->empresa->var2str($this->desde)
531
            . " AND f.fecha <= " . $this->empresa->var2str($this->hasta);
532
533
        if ($this->codserie) {
534
            $sql .= " AND f.codserie = " . $this->empresa->var2str($this->codserie);
535
        }
536
537
        if ($this->codalmacen) {
538
            $sql .= " AND f.codalmacen = " . $this->empresa->var2str($this->codalmacen);
539
        }
540
541
        if ($this->codagente) {
542
            $sql .= " AND f.codagente = " . $this->empresa->var2str($this->codagente);
543
        }
544
545
        if ($this->proveedor) {
546
            $sql .= " AND codproveedor = " . $this->empresa->var2str($this->proveedor->codproveedor);
547
        }
548
549
        if ($_POST['minimo']) {
550
            $sql .= " AND l.cantidad > " . $this->empresa->var2str($_POST['minimo']);
551
        }
552
553
        $sql .= " GROUP BY f.codalmacen,f.codproveedor,f.fecha,l.referencia,l.descripcion ORDER BY f.codproveedor ASC, l.referencia ASC, f.fecha DESC;";
554
555
        $data = $this->db->select($sql);
556
        if ($data) {
557
            $this->template = FALSE;
558
            header("content-type:application/csv;charset=UTF-8");
559
            header("Content-Disposition: attachment; filename=\"informe_compras_unidades.csv\"");
560
            echo "almacen;codproveedor;nombre;referencia;descripcion;año;ene;feb;mar;abr;may;jun;jul;ago;sep;oct;nov;dic;total;%VAR\n";
561
562
            $proveedor = new proveedor();
563
            $stats = array();
564
565
            foreach ($data as $d) {
566
                $anyo = date('Y', strtotime($d['fecha']));
567
                $mes = date('n', strtotime($d['fecha']));
568
                if (!isset($stats[$d['codproveedor']][$d['referencia']][$anyo])) {
569
                    $stats[$d['codproveedor']][$d['referencia']][$anyo] = [
570
                        1 => 0,
571
                        2 => 0,
572
                        3 => 0,
573
                        4 => 0,
574
                        5 => 0,
575
                        6 => 0,
576
                        7 => 0,
577
                        8 => 0,
578
                        9 => 0,
579
                        10 => 0,
580
                        11 => 0,
581
                        12 => 0,
582
                        13 => 0,
583
                        14 => 0,
584
                        15 => $d['codalmacen'],
585
                        16 => $d['descripcion'],
586
                    ];
587
                }
588
589
                $stats[$d['codproveedor']][$d['referencia']][$anyo][$mes] += (float)$d['total'];
590
                $stats[$d['codproveedor']][$d['referencia']][$anyo][13] += (float)$d['total'];
591
            }
592
593
            foreach ($stats as $i => $value) {
594
                $pro = $proveedor->get($i);
595
                foreach ($value as $j => $value2) {
596
                    /// calculamos la variación
597
                    $anterior = 0;
598
                    foreach (array_reverse($value2, true) as $k => $value3) {
599
                        if ($anterior > 0) {
600
                            $value2[$k][14] = ($value3[13] * 100 / $anterior) - 100;
601
                        }
602
                        $anterior = $value3[13];
603
                    }
604
605
                    foreach ($value2 as $k => $value3) {
606
                        if ($pro) {
607
                            echo '"' . $value2[$k][15] . '";' . '"' . $i . '";' . fs_fix_html($pro->nombre) . ';"' . $j . '";' . '"' . $value2[$k][16] . '"' . ';' . $k;
608
                        } else {
609
                            echo '"' . $value2[$k][15] . '";' . '"' . $i . '";-;"' . $j . '";' . '"' . $value2[$k][16] . '"' . ';' . $k;
610
                        }
611
612
                        foreach ($value3 as $x => $value4) {
613
                            if ($x < 15) {
614
                                echo ';' . $this->show_numero($value4, FS_NF0);
615
                            }
616
                        }
617
                        echo "\n";
618
                    }
619
                    echo ";;;;;;;;;;;;;;;\n";
620
                }
621
                echo ";;;;;;;;;;;;;;;\n";
622
            }
623
        } else {
624
            $this->new_error_msg('Sin resultados.');
625
        }
626
    }
627
628
    private function informe_ventas_unidades()
629
    {
630
        $sql = "SELECT f.codalmacen,f.codcliente,f.fecha,l.referencia,l.descripcion,SUM(l.cantidad) as total"
631
            . " FROM facturascli f, lineasfacturascli l"
632
            . " WHERE f.idfactura = l.idfactura AND l.referencia IS NOT NULL AND anulada = false "
633
            . " AND f.fecha >= " . $this->empresa->var2str($this->desde)
634
            . " AND f.fecha <= " . $this->empresa->var2str($this->hasta);
635
636
        if ($_POST['codpais']) {
637
            $sql .= " AND f.codpais = " . $this->empresa->var2str($_POST['codpais']);
638
        }
639
640
        if ($_POST['provincia']) {
641
            $sql .= " AND lower(f.provincia) = lower(" . $this->empresa->var2str($_POST['provincia']) . ")";
642
        }
643
644
        if ($this->cliente) {
645
            $sql .= " AND codcliente = " . $this->empresa->var2str($this->cliente->codcliente);
646
        }
647
648
        if ($this->codalmacen) {
649
            $sql .= " AND f.codalmacen = " . $this->empresa->var2str($this->codalmacen);
650
        }
651
652
        if ($this->codserie) {
653
            $sql .= " AND f.codserie = " . $this->empresa->var2str($this->codserie);
654
        }
655
656
        if ($this->codagente) {
657
            $sql .= " AND f.codagente = " . $this->empresa->var2str($this->codagente);
658
        }
659
660
        if ($_POST['minimo']) {
661
            $sql .= " AND l.cantidad > " . $this->empresa->var2str($_POST['minimo']);
662
        }
663
664
        $sql .= " GROUP BY f.codalmacen,f.codcliente,f.fecha,l.referencia,l.descripcion ORDER BY f.codcliente ASC, l.referencia ASC, f.fecha DESC;";
665
666
        $data = $this->db->select($sql);
667
        if ($data) {
668
            $this->template = FALSE;
669
670
            header("content-type:application/csv;charset=UTF-8");
671
            header("Content-Disposition: attachment; filename=\"informe_ventas_unidades.csv\"");
672
            echo "almacen;codcliente;nombre;referencia;descripcion;año;ene;feb;mar;abr;may;jun;jul;ago;sep;oct;nov;dic;total;%VAR\n";
673
674
            $cliente = new cliente();
675
            $stats = array();
676
            foreach ($data as $d) {
677
                $anyo = date('Y', strtotime($d['fecha']));
678
                $mes = date('n', strtotime($d['fecha']));
679
                if (!isset($stats[$d['codcliente']][$d['referencia']][$anyo])) {
680
                    $stats[$d['codcliente']][$d['referencia']][$anyo] = array(
681
                        1 => 0,
682
                        2 => 0,
683
                        3 => 0,
684
                        4 => 0,
685
                        5 => 0,
686
                        6 => 0,
687
                        7 => 0,
688
                        8 => 0,
689
                        9 => 0,
690
                        10 => 0,
691
                        11 => 0,
692
                        12 => 0,
693
                        13 => 0,
694
                        14 => 0,
695
                        15 => $d['codalmacen'],
696
                        16 => $d['descripcion'],
697
                    );
698
                }
699
700
                $stats[$d['codcliente']][$d['referencia']][$anyo][$mes] += (float)$d['total'];
701
                $stats[$d['codcliente']][$d['referencia']][$anyo][13] += (float)$d['total'];
702
            }
703
704
            foreach ($stats as $i => $value) {
705
                $cli = $cliente->get($i);
706
                foreach ($value as $j => $value2) {
707
                    /// calculamos la variación
708
                    $anterior = 0;
709
                    foreach (array_reverse($value2, true) as $k => $value3) {
710
                        if ($anterior > 0) {
711
                            $value2[$k][14] = ($value3[13] * 100 / $anterior) - 100;
712
                        }
713
714
                        $anterior = $value3[13];
715
                    }
716
717
                    foreach ($value2 as $k => $value3) {
718
                        if ($cli) {
719
                            echo '"' . $value2[$k][15] . '";' . '"' . $i . '";' . fs_fix_html($cli->nombre) . ';"' . $j . '";' . '"' . $value2[$k][16] . '"' . ';' . $k;
720
                        } else {
721
                            echo '"' . $value2[$k][15] . '";' . '"' . $i . '";-;"' . $j . '";' . '"' . $value2[$k][16] . '"' . ';' . $k;
722
                        }
723
724
                        foreach ($value3 as $x => $value4) {
725
                            if ($x < 15) {
726
                                echo ';' . $this->show_numero($value4, FS_NF0);
727
                            }
728
                        }
729
730
                        echo "\n";
731
                    }
732
                    echo ";;;;;;;;;;;;;;;;\n";
733
                }
734
                echo ";;;;;;;;;;;;;;;;\n";
735
            }
736
        } else {
737
            $this->new_error_msg('Sin resultados.');
738
        }
739
    }
740
741
    protected function ini_filters()
742
    {
743
        parent::ini_filters();
744
745
        $this->estado = FALSE;
746
        if (isset($_REQUEST['estado'])) {
747
            $this->estado = $_REQUEST['estado'];
748
        }
749
    }
750
751
    protected function set_where()
752
    {
753
        parent::set_where();
754
755
        if ($this->estado) {
756
            $estado = $this->estado === 'pagada' ? true : false;
757
            $this->where_compras .= " AND pagada = " . $this->empresa->var2str($estado);
758
            $this->where_ventas .= " AND pagada = " . $this->empresa->var2str($estado);
759
        }
760
    }
761
762
    protected function generar_pdf($tipo = 'compra')
763
    {
764
        /// desactivamos el motor de plantillas
765
        $this->template = false;
766
767
        $pdf_doc = new fs_pdf('a4', 'landscape', 'Courier');
768
        $pdf_doc->pdf->addInfo('Title', $this->nombre_docs . ' de ' . $tipo . ' del ' . $this->desde . ' al ' . $this->hasta);
769
        $pdf_doc->pdf->addInfo('Subject', $this->nombre_docs . ' de ' . $tipo . ' del ' . $this->desde . ' al ' . $this->hasta);
770
        $pdf_doc->pdf->addInfo('Author', fs_fix_html($this->empresa->nombre));
771
772
        $cliente = 'Proveedor';
773
        $num2 = 'Num. proveedor';
774
        $tabla = $this->table_compras;
775
        if ($tipo === 'venta') {
776
            $cliente = 'Cliente';
777
            $num2 = FS_NUMERO2;
778
            $tabla = $this->table_ventas;
779
        }
780
781
        $encabezado = fs_fix_html($this->empresa->nombre) . ' - ' . $this->nombre_docs
782
            . ' de ' . $tipo . ' del ' . $this->desde . ' al ' . $this->hasta;
783
784
        if ($this->codagente) {
785
            $encabezado .= ', empleado: ' . $this->codagente;
786
        }
787
788
        if ($this->codserie) {
789
            $encabezado .= ', serie: ' . $this->codserie;
790
        }
791
792
        if ($this->coddivisa) {
793
            $encabezado .= ', divisa: ' . $this->coddivisa;
794
        }
795
796
        if ($this->codpago) {
797
            $encabezado .= ', forma de pago: ' . $this->codpago;
798
        }
799
800
        if ($this->codalmacen) {
801
            $encabezado .= ', almacén ' . $this->codalmacen;
802
        }
803
804
        $documentos = $this->get_documentos($tabla);
805
        if (!empty($documentos)) {
806
            $total_lineas = count($documentos);
807
            $linea_actual = 0;
808
            $lppag = 72;
809
            $pagina = 1;
810
            $neto = $totaliva = $totalre = $totalirpf = $total = 0;
811
812
            while ($linea_actual < $total_lineas) {
813
                if ($linea_actual > 0) {
814
                    $pdf_doc->pdf->ezNewPage();
815
                    $pagina++;
816
                }
817
818
                /// encabezado
819
                $pdf_doc->pdf->ezText($encabezado . ".\n\n");
820
821
                /// tabla principal
822
                $pdf_doc->new_table();
823
                $pdf_doc->add_table_header(
824
                    array(
825
                        'serie' => '<b>' . strtoupper(FS_SERIE) . '</b>',
826
                        'doc' => '<b>Documento</b>',
827
                        'num2' => '<b>' . $num2 . '</b>',
828
                        'fecha' => '<b>Fecha</b>',
829
                        'cliente' => '<b>' . $cliente . '</b>',
830
                        'cifnif' => '<b>' . FS_CIFNIF . '</b>',
831
                        'neto' => '<b>Neto</b>',
832
                        'tasaiva' => '<b>%' . FS_IVA . '</b>',
833
                        'iva' => '<b>' . FS_IVA . '</b>',
834
                        'tasare' => '<b>%RE</b>',
835
                        're' => '<b>RE</b>',
836
                        'irpf' => '<b>' . FS_IRPF . '</b>',
837
                        'total' => '<b>Total</b>'
838
                    )
839
                );
840
841
                for ($i = 0; $i < $lppag && $linea_actual < $total_lineas; $i++) {
842
                    $linea = array(
843
                        'serie' => $documentos[$linea_actual]->codserie,
844
                        'doc' => $documentos[$linea_actual]->codigo,
845
                        'num2' => '',
846
                        'fecha' => $documentos[$linea_actual]->fecha,
847
                        'cliente' => '',
848
                        'cifnif' => $documentos[$linea_actual]->cifnif,
849
                        'neto' => $this->show_numero($documentos[$linea_actual]->neto),
850
                        'tasaiva' => $this->show_numero($documentos[$linea_actual]->tasaiva),
851
                        FS_IVA => $this->show_numero($documentos[$linea_actual]->totaliva),
852
                        'tasare' => $this->show_numero($documentos[$linea_actual]->tasare),
853
                        're' => $this->show_numero($documentos[$linea_actual]->totalrecargo),
854
                        'irpf' => $this->show_numero($documentos[$linea_actual]->totalirpf),
855
                        'total' => $this->show_numero($documentos[$linea_actual]->total),
856
                    );
857
858
                    if ($tipo === 'compra') {
859
                        $linea['num2'] = fs_fix_html($documentos[$linea_actual]->numproveedor);
860
                        $linea['cliente'] = fs_fix_html($documentos[$linea_actual]->nombre);
861
                    } else {
862
                        $linea['num2'] = fs_fix_html($documentos[$linea_actual]->numero2);
863
                        $linea['cliente'] = fs_fix_html($documentos[$linea_actual]->nombrecliente);
864
                    }
865
866
                    $pdf_doc->add_table_row($linea);
867
868
                    $neto += $documentos[$linea_actual]->neto;
869
                    $totaliva += $documentos[$linea_actual]->totaliva;
870
                    $totalre += $documentos[$linea_actual]->totalrecargo;
871
                    $totalirpf += $documentos[$linea_actual]->totalirpf;
872
                    $total += $documentos[$linea_actual]->total;
873
                    $i++;
874
                    $linea_actual++;
875
                }
876
877
                /// añadimos el subtotal
878
                $linea = array(
879
                    'serie' => '',
880
                    'doc' => '',
881
                    'num2' => '',
882
                    'fecha' => '',
883
                    'cliente' => '',
884
                    'cifnif' => '',
885
                    'neto' => '<b>' . $this->show_numero($neto) . '</b>',
886
                    'tasaiva' => '',
887
                    FS_IVA => '<b>' . $this->show_numero($totaliva) . '</b>',
888
                    'tasare' => '',
889
                    're' => '<b>' . $this->show_numero($totalre) . '</b>',
890
                    'irpf' => '<b>' . $this->show_numero($totalirpf) . '</b>',
891
                    'total' => '<b>' . $this->show_numero($total) . '</b>',
892
                );
893
                $pdf_doc->add_table_row($linea);
894
895
                $pdf_doc->save_table(
896
                    array(
897
                        'fontSize' => 8,
898
                        'cols' => array(
899
                            'neto' => array('justification' => 'right'),
900
                            'tasaiva' => array('justification' => 'right'),
901
                            FS_IVA => array('justification' => 'right'),
902
                            'tasare' => array('justification' => 'right'),
903
                            're' => array('justification' => 'right'),
904
                            'irpf' => array('justification' => 'right'),
905
                            'total' => array('justification' => 'right')
906
                        ),
907
                        'shaded' => 0,
908
                        'width' => 780
909
                    )
910
                );
911
            }
912
913
            $this->desglose_impuestos_pdf($pdf_doc, $tipo);
914
        } else {
915
            $pdf_doc->pdf->ezText($encabezado . '.');
916
            $pdf_doc->pdf->ezText("\nSin resultados.", 14);
917
        }
918
919
        $pdf_doc->show();
920
    }
921
922
    protected function generar_xls($tipo = 'compra')
923
    {
924
        /// desactivamos el motor de plantillas
925
        $this->template = false;
926
927
        header("Content-Disposition: attachment; filename=\"informe_" . $this->nombre_docs . "_" . time() . ".xlsx\"");
928
        header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
929
        header('Content-Transfer-Encoding: binary');
930
        header('Cache-Control: must-revalidate');
931
        header('Pragma: public');
932
933
        $header = array(
934
            'serie' => 'string',
935
            'doc' => 'string',
936
            FS_NUMERO2 => 'string',
937
            'num.proveedor' => 'string',
938
            'fecha' => 'string',
939
            'cliente' => 'string',
940
            'proveedor' => 'string',
941
            FS_CIFNIF => 'string',
942
            'direccion' => 'string',
943
            'neto' => '#,##0.00;[RED]-#,##0.00',
944
            'tasaiva' => '#,##0.00;[RED]-#,##0.00',
945
            FS_IVA => '#,##0.00;[RED]-#,##0.00',
946
            'tasare' => '#,##0.00;[RED]-#,##0.00',
947
            're' => '#,##0.00;[RED]-#,##0.00',
948
            'irpf' => '#,##0.00;[RED]-#,##0.00',
949
            'total' => '#,##0.00;[RED]-#,##0.00',
950
        );
951
952
        if ($tipo === 'compra') {
953
            $tabla = $this->table_compras;
954
            unset($header[FS_NUMERO2]);
955
            unset($header['cliente']);
956
        } else {
957
            $tabla = $this->table_ventas;
958
            unset($header['num.proveedor']);
959
            unset($header['proveedor']);
960
        }
961
962
        $writer = new XLSXWriter();
0 ignored issues
show
Bug introduced by
The type XLSXWriter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
963
        $writer->setAuthor('FacturaScripts');
964
        $writer->writeSheetHeader($this->nombre_docs, $header);
965
966
        foreach ($this->get_documentos($tabla) as $doc) {
967
            $linea = array(
968
                'serie' => $doc->codserie,
969
                'doc' => $doc->codigo,
970
                FS_NUMERO2 => '',
971
                'num.proveedor' => '',
972
                'fecha' => $doc->fecha,
973
                'cliente' => '',
974
                'proveedor' => '',
975
                FS_CIFNIF => $doc->cifnif,
976
                'direccion' => $doc->direccion,
977
                'neto' => $doc->neto,
978
                'tasaiva' => $doc->tasaiva,
979
                FS_IVA => $doc->totaliva,
980
                'tasare' => $doc->tasare,
981
                're' => $doc->totalrecargo,
982
                'irpf' => $doc->totalirpf,
983
                'total' => $doc->total,
984
            );
985
986
            if ($tipo === 'compra') {
987
                $linea['num.proveedor'] = $doc->numproveedor;
988
                $linea['proveedor'] = $doc->nombre;
989
                unset($linea[FS_NUMERO2]);
990
                unset($linea['cliente']);
991
            } else {
992
                $linea[FS_NUMERO2] = $doc->numero2;
993
                $linea['cliente'] = $doc->nombrecliente;
994
                unset($linea['num.proveedor']);
995
                unset($linea['proveedor']);
996
            }
997
998
            $writer->writeSheetRow($this->nombre_docs, $linea);
999
        }
1000
1001
        $writer->writeToStdOut();
1002
    }
1003
1004
    protected function generar_csv($tipo = 'compra')
1005
    {
1006
        /// desactivamos el motor de plantillas
1007
        $this->template = false;
1008
1009
        header("content-type:application/csv;charset=UTF-8");
1010
        header("Content-Disposition: attachment; filename=\"informe_" . $this->nombre_docs . "_" . time() . ".csv\"");
1011
1012
        if ($tipo === 'compra') {
1013
            $tabla = $this->table_compras;
1014
            echo "serie,documento,num.proveedor,fecha,proveedor,direccion," . FS_CIFNIF . ",neto,tasa" . FS_IVA
1015
            . "," . FS_IVA . ",tasare,re," . FS_IRPF . ",total\n";
1016
        } else {
1017
            $tabla = $this->table_ventas;
1018
            echo "serie,documento," . FS_NUMERO2 . ",fecha,cliente,direccion," . FS_CIFNIF . ",neto,tasa" . FS_IVA
1019
            . "," . FS_IVA . ",tasare,re," . FS_IRPF . ",total\n";
1020
        }
1021
1022
        foreach ($this->get_documentos($tabla) as $doc) {
1023
            $linea = array(
1024
                'serie' => $doc->codserie,
1025
                'doc' => $doc->codigo,
1026
                FS_NUMERO2 => '',
1027
                'num.proveedor' => '',
1028
                'fecha' => $doc->fecha,
1029
                'cliente' => '',
1030
                'direccion' => $doc->fecha,
1031
                'cifnif' => $doc->cifnif,
1032
                'neto' => $doc->neto,
1033
                'tasaiva' => $doc->tasaiva,
1034
                FS_IVA => $doc->totaliva,
1035
                'tasare' => $doc->tasare,
1036
                're' => $doc->totalrecargo,
1037
                'irpf' => $doc->totalirpf,
1038
                'total' => $doc->total,
1039
            );
1040
1041
            if ($tipo === 'compra') {
1042
                $linea['num.proveedor'] = $doc->numproveedor;
1043
                $linea['cliente'] = fs_fix_html($doc->nombre);
1044
                unset($linea[FS_NUMERO2]);
1045
            } else {
1046
                $linea[FS_NUMERO2] = $doc->numero2;
1047
                $linea['cliente'] = fs_fix_html($doc->nombrecliente);
1048
                unset($linea['num.proveedor']);
1049
            }
1050
1051
            echo '"' . implode('","', $linea) . "\"\n";
1052
        }
1053
    }
1054
}
1055