Tul xxx Tul
User / IP
:
216.73.216.227
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
vendefacil2
/
controllers
/
Viewing: Reportes.php
<?php require 'vendor/autoload.php'; use Dompdf\Dompdf; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Style\Fill; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Alignment; class Reportes extends Controller { private $id_usuario, $id_sucursal; public function __construct() { parent::__construct(); session_start(); if (empty($_SESSION['id_usuario'])) { header('Location: ' . BASE_URL); exit; } $this->id_usuario = $_SESSION['id_usuario']; $this->id_sucursal = $_SESSION['id_sucursal']; } public function index() { header('Location: ' . BASE_URL . 'reportes/ventas'); exit; } public function ventas() { $data['title'] = 'Historial de Ventas'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $vendedor = $_GET['vendedor'] ?? 'todos'; $cajero = $_GET['cajero'] ?? 'todos'; $cliente = $_GET['cliente'] ?? 'todos'; $data['vendedores'] = $this->model->getVendedores($this->id_sucursal); $data['cajeros'] = $this->model->getVendedores($this->id_sucursal); $data['clientes'] = $this->model->getClientes($this->id_sucursal); $data['lista'] = $this->model->getVentasDetalleReporte($fecha_inicio, $fecha_fin, $vendedor, $cajero, $cliente, $this->id_sucursal); $this->views->getView('reportes', 'ventas', $data); } public function taller() { $data['title'] = 'Ventas de Taller'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $estado = $_GET['estado'] ?? 'todos'; $tecnico = $_GET['tecnico'] ?? 'todos'; $data['tecnicos'] = $this->model->getVendedores($this->id_sucursal); $data['lista'] = $this->model->getVentasTaller($fecha_inicio, $fecha_fin, $estado, $tecnico, $this->id_sucursal); $this->views->getView('reportes', 'taller', $data); } public function generarTaller() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $estado = $_GET['estado'] ?? 'todos'; $tecnico = $_GET['tecnico'] ?? 'todos'; $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $logoPath = 'assets/images/logo.png'; if (file_exists($logoPath)) { $data['logo'] = 'data:image/png;base64,' . base64_encode(file_get_contents($logoPath)); } else { $data['logo'] = null; } $data['lista'] = $this->model->getVentasTaller($fecha_inicio, $fecha_fin, $estado, $tecnico, $this->id_sucursal); $data['desde'] = $fecha_inicio; $data['hasta'] = $fecha_fin; ob_start(); $this->views->getView('reportes', 'pdf_taller', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'landscape'); $dompdf->render(); $dompdf->stream('Ventas_de_Taller.pdf', array('Attachment' => false)); } public function excelTaller() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $estado = $_GET['estado'] ?? 'todos'; $tecnico = $_GET['tecnico'] ?? 'todos'; $lista = $this->model->getVentasTaller($fecha_inicio, $fecha_fin, $estado, $tecnico, $this->id_sucursal); $spreadsheet = new Spreadsheet(); $spreadsheet->getProperties() ->setCreator($_SESSION['nombre_usuario']) ->setTitle("Ventas de Taller"); $spreadsheet->setActiveSheetIndex(0); $hojaActiva = $spreadsheet->getActiveSheet(); // Anchos de columna $hojaActiva->getColumnDimension('A')->setWidth(15); $hojaActiva->getColumnDimension('B')->setWidth(25); $hojaActiva->getColumnDimension('C')->setWidth(25); $hojaActiva->getColumnDimension('D')->setWidth(30); $hojaActiva->getColumnDimension('E')->setWidth(20); $hojaActiva->getColumnDimension('F')->setWidth(15); $hojaActiva->getColumnDimension('G')->setWidth(18); $hojaActiva->getColumnDimension('H')->setWidth(18); // Estilos de cabecera $spreadsheet->getActiveSheet()->getStyle('A1:H1')->getFill() ->setFillType(Fill::FILL_SOLID) ->getStartColor()->setARGB('008cff'); $spreadsheet->getActiveSheet()->getStyle('A1:H1') ->getFont()->getColor()->setARGB(Color::COLOR_WHITE); $hojaActiva->setCellValue('A1', 'FECHA'); $hojaActiva->setCellValue('B1', 'CLIENTE'); $hojaActiva->setCellValue('C1', 'EQUIPO'); $hojaActiva->setCellValue('D1', 'PROBLEMA'); $hojaActiva->setCellValue('E1', 'TÉCNICO'); $hojaActiva->setCellValue('F1', 'ESTADO'); $hojaActiva->setCellValue('G1', 'PRECIO PAGADO'); $hojaActiva->setCellValue('H1', 'PRECIO VENTA'); $fila = 2; foreach ($lista as $row) { $hojaActiva->setCellValue('A' . $fila, $row['fecha']); $hojaActiva->setCellValue('B' . $fila, $row['cliente']); $hojaActiva->setCellValue('C' . $fila, $row['equipo']); $hojaActiva->setCellValue('D' . $fila, $row['problema']); $hojaActiva->setCellValue('E' . $fila, $row['tecnico']); $hojaActiva->setCellValue('F' . $fila, strtoupper($row['estado'])); $hojaActiva->setCellValue('G' . $fila, number_format((float)$row['precio_pagado'], 2, '.', '')); $hojaActiva->setCellValue('H' . $fila, number_format((float)$row['precio_venta'], 2, '.', '')); $fila++; } header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="Ventas_Taller.xlsx"'); $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output'); } public function traslados() { $data['title'] = 'Traslados'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $vendedor = $_GET['vendedor'] ?? 'todos'; $cajero = $_GET['cajero'] ?? 'todos'; $cliente = $_GET['cliente'] ?? 'todos'; $data['cajeros'] = $this->model->getVendedores($this->id_sucursal); $data['vendedores'] = $this->model->getVendedores($this->id_sucursal); $data['clientes'] = $this->model->getClientes($this->id_sucursal); $data['lista'] = $this->model->getTrasladosDetalleReporte($fecha_inicio, $fecha_fin, $vendedor, $cajero, $cliente, $this->id_sucursal); $this->views->getView('reportes', 'traslados', $data); } public function generarTraslados() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $vendedor = $_GET['vendedor'] ?? 'todos'; $cajero = $_GET['cajero'] ?? 'todos'; $cliente = $_GET['cliente'] ?? 'todos'; $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $logoPath = 'assets/images/logo.png'; if (file_exists($logoPath)) { $data['logo'] = 'data:image/png;base64,' . base64_encode(file_get_contents($logoPath)); } else { $data['logo'] = null; } $data['lista'] = $this->model->getTrasladosDetalleReporte($fecha_inicio, $fecha_fin, $vendedor, $cajero, $cliente, $this->id_sucursal); $data['desde'] = $fecha_inicio; $data['hasta'] = $fecha_fin; ob_start(); $this->views->getView('reportes', 'pdf_traslados', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'landscape'); $dompdf->render(); $dompdf->stream('Traslados_Inventario.pdf', array('Attachment' => false)); } public function excelTraslados() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $vendedor = $_GET['vendedor'] ?? 'todos'; $cajero = $_GET['cajero'] ?? 'todos'; $cliente = $_GET['cliente'] ?? 'todos'; $lista = $this->model->getTrasladosDetalleReporte($fecha_inicio, $fecha_fin, $vendedor, $cajero, $cliente, $this->id_sucursal); $spreadsheet = new Spreadsheet(); $spreadsheet->getProperties() ->setCreator($_SESSION['nombre_usuario']) ->setTitle("Traslados de Inventario"); $spreadsheet->setActiveSheetIndex(0); $hojaActiva = $spreadsheet->getActiveSheet(); // Anchos de columna $hojaActiva->getColumnDimension('A')->setWidth(15); $hojaActiva->getColumnDimension('B')->setWidth(20); $hojaActiva->getColumnDimension('C')->setWidth(30); $hojaActiva->getColumnDimension('D')->setWidth(20); $hojaActiva->getColumnDimension('E')->setWidth(20); $hojaActiva->getColumnDimension('F')->setWidth(15); $hojaActiva->getColumnDimension('G')->setWidth(18); $hojaActiva->getColumnDimension('H')->setWidth(18); // Estilos de cabecera $spreadsheet->getActiveSheet()->getStyle('A1:H1')->getFill() ->setFillType(Fill::FILL_SOLID) ->getStartColor()->setARGB('008cff'); $spreadsheet->getActiveSheet()->getStyle('A1:H1') ->getFont()->getColor()->setARGB(Color::COLOR_WHITE); $hojaActiva->setCellValue('A1', 'CODIGO'); $hojaActiva->setCellValue('B1', 'CATEGORIA'); $hojaActiva->setCellValue('C1', 'PRODUCTO'); $hojaActiva->setCellValue('D1', 'ORIGEN'); $hojaActiva->setCellValue('E1', 'DESTINO'); $hojaActiva->setCellValue('F1', 'CANTIDADES'); $hojaActiva->setCellValue('G1', 'PRECIO COSTO'); $hojaActiva->setCellValue('H1', 'COSTO TOTAL'); $fila = 2; foreach ($lista as $row) { $hojaActiva->setCellValue('A' . $fila, $row['codigo']); $hojaActiva->setCellValue('B' . $fila, $row['categoria']); $hojaActiva->setCellValue('C' . $fila, $row['producto']); $hojaActiva->setCellValue('D' . $fila, $row['origen']); $hojaActiva->setCellValue('E' . $fila, $row['destino']); $hojaActiva->setCellValue('F' . $fila, $row['cantidad']); $hojaActiva->setCellValue('G' . $fila, number_format((float)$row['precio_costo'], 2, '.', '')); $hojaActiva->setCellValue('H' . $fila, number_format((float)$row['costo_total'], 2, '.', '')); $fila++; } header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="Traslados_Inventario.xlsx"'); $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output'); } public function apartados() { $data['title'] = 'Apartados'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data['clientes'] = $this->model->getClientes($this->id_sucursal); $data['lista'] = $this->model->getApartados($fecha_inicio, $fecha_fin, $cliente, $estado, $this->id_sucursal); foreach ($data['lista'] as &$row) { $row['pendiente'] = (float)$row['total'] - (float)$row['abono']; $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Completado' : 'Pendiente'; } unset($row); $this->views->getView('reportes', 'apartados', $data); } public function inventarios() { $data['title'] = 'Inventarios'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $categoria = $_GET['categoria'] ?? 'todos'; $bodega = $_GET['bodega'] ?? 'todos'; $vencimiento = $_GET['vencimiento'] ?? ''; $data['categorias'] = $this->model->getCategorias(); $data['sucursales'] = $this->model->selectAll("SELECT id, nombre FROM sucursales"); $data['lista'] = $this->model->getInventario($fecha_inicio, $fecha_fin, $categoria, $bodega, $vencimiento, $this->id_sucursal); foreach ($data['lista'] as &$row) { $es_servicio = (int)($row['servicio'] ?? 0) === 1; $has_lote = isset($row['lote_id']) && $row['lote_id'] !== null; $stock = $es_servicio ? 0 : ($has_lote ? (float)$row['lote_cantidad'] : (float)($row['cantidad'] ?? 0)); $row['stock_numeric'] = $stock; $row['fecha_venc'] = $es_servicio ? 'N/A' : ($has_lote ? $row['lote_fecha'] : ($row['fecha_vencimiento'] ?? 'N/A')); $precio_compra = (float)$row['precio_compra']; $row['total_inversion'] = $es_servicio ? 0.0 : ($precio_compra * $stock); $precio_venta = $row['precio_venta']; $preciosVentaArr = json_decode($precio_venta, true); if (is_array($preciosVentaArr) && count($preciosVentaArr) > 0) { $precio_venta = $preciosVentaArr[0]['monto']; } $precio_venta = (float)$precio_venta; $row['precio_venta_val'] = $precio_venta; $utilidad = $precio_venta - $precio_compra; $row['utilidad'] = $utilidad; if ($precio_compra > 0) { $row['rentabilidad'] = ($utilidad / $precio_compra) * 100; } else { $row['rentabilidad'] = 100; } } unset($row); $this->views->getView('reportes', 'inventarios', $data); } public function salidas() { $data['title'] = 'Salidas de Inventario'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $motivo = $_GET['motivo'] ?? 'todos'; $data['lista'] = $this->model->getSalidasInventario($fecha_inicio, $fecha_fin, $motivo, $this->id_sucursal); $this->views->getView('reportes', 'salidas', $data); } public function compras() { $data['title'] = 'Reporte de Compras'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $proveedor = $_GET['proveedor'] ?? 'todos'; $data['proveedores'] = $this->model->getProveedores($this->id_sucursal); $data['lista'] = $this->model->getCompras($fecha_inicio, $fecha_fin, $proveedor, $this->id_sucursal); foreach ($data['lista'] as &$row) { $row['situacion'] = (int)$row['estado'] === 1 ? 'Activa' : 'Anulada'; } unset($row); $this->views->getView('reportes', 'compras', $data); } public function gastos() { $data['title'] = 'Reporte de Gastos'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $categoria = $_GET['categoria'] ?? 'todos'; $subcategoria = $_GET['subcategoria'] ?? 'todos'; $data['categorias'] = $this->model->selectAll("SELECT DISTINCT categoria FROM gastos WHERE id_sucursal = " . $this->id_sucursal . " AND categoria IS NOT NULL AND categoria != ''"); $data['subcategorias'] = $this->model->selectAll("SELECT DISTINCT subcategoria FROM gastos WHERE id_sucursal = " . $this->id_sucursal . " AND subcategoria IS NOT NULL AND subcategoria != ''"); $data['lista'] = $this->model->getGastos($fecha_inicio, $fecha_fin, $categoria, $subcategoria, $this->id_sucursal); $this->views->getView('reportes', 'gastos', $data); } public function cuentas_cobrar() { $data['title'] = 'Reporte de Cuentas por Cobrar'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data['clientes'] = $this->model->getClientes($this->id_sucursal); $data['lista'] = $this->model->getCuentasCobrar($fecha_inicio, $fecha_fin, $cliente, $estado, $this->id_sucursal); foreach ($data['lista'] as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Pendiente' : 'Pagado'; } unset($row); $this->views->getView('reportes', 'cuentas_cobrar', $data); } public function cuentas_pagar() { $data['title'] = 'Reporte de Cuentas por Pagar'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $proveedor = $_GET['proveedor'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data['proveedores'] = $this->model->getProveedores($this->id_sucursal); $data['lista'] = $this->model->getCuentasPagar($fecha_inicio, $fecha_fin, $proveedor, $estado, $this->id_sucursal); foreach ($data['lista'] as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Pendiente' : 'Pagado'; } unset($row); $this->views->getView('reportes', 'cuentas_pagar', $data); } public function estado_resultados() { header('Location: ' . BASE_URL . 'estadoresultado'); exit; } public function activo_fijo() { $data['title'] = 'Reporte de Activo Fijo'; $data['script'] = 'reportes.js'; $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $estado = $_GET['estado'] ?? 'todos'; $data['lista'] = $this->model->getActivosFijos($fecha_inicio, $fecha_fin, $estado, $this->id_sucursal); foreach ($data['lista'] as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Activo' : 'Inactivo'; } unset($row); $this->views->getView('reportes', 'activo_fijo', $data); } public function rentabilidad_productos() { $data['title'] = 'Reporte de Rentabilidad por Producto'; $data['script'] = 'reportes.js'; $codigo = $_GET['codigo'] ?? ''; $nombre = $_GET['nombre'] ?? ''; $lista = $this->model->getRentabilidadProductos($codigo, $nombre, $this->id_sucursal); foreach ($lista as &$row) { $costo = (float)$row['precio_compra']; $preciosVentaArr = json_decode($row['precio_venta'], true); $venta = is_array($preciosVentaArr) && !empty($preciosVentaArr) ? (float)$preciosVentaArr[0]['monto'] : (float)$row['precio_venta']; $row['precio_venta'] = $venta; $utilidad = $venta - $costo; $porcentaje = $costo > 0 ? ($utilidad / $costo) * 100 : 100; $row['utilidad'] = $utilidad; $row['porcentaje_utilidad'] = $porcentaje; } unset($row); $data['lista'] = $lista; $this->views->getView('reportes', 'rentabilidad_productos', $data); } public function generarInventario() { // Aumentar límite de memoria y tiempo ilimitado para inventarios muy grandes ini_set('memory_limit', '4096M'); set_time_limit(0); $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $categoria = $_GET['categoria'] ?? 'todos'; $bodega = $_GET['bodega'] ?? 'todos'; $vencimiento = $_GET['vencimiento'] ?? ''; $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['lista'] = $this->model->getInventario($fecha_inicio, $fecha_fin, $categoria, $bodega, $vencimiento, $this->id_sucursal); foreach ($data['lista'] as &$row) { $es_servicio = (int)($row['servicio'] ?? 0) === 1; $has_lote = isset($row['lote_id']) && $row['lote_id'] !== null; $stock = $es_servicio ? 0 : ($has_lote ? (float)$row['lote_cantidad'] : (float)($row['cantidad'] ?? 0)); $row['stock_numeric'] = $stock; $row['fecha_venc'] = $es_servicio ? 'N/A' : ($has_lote ? $row['lote_fecha'] : ($row['fecha_vencimiento'] ?? 'N/A')); $precio_compra = (float)$row['precio_compra']; $row['total_inversion'] = $es_servicio ? 0.0 : ($precio_compra * $stock); $precio_venta = $row['precio_venta']; $preciosVentaArr = json_decode($precio_venta, true); if (is_array($preciosVentaArr) && count($preciosVentaArr) > 0) { $precio_venta = $preciosVentaArr[0]['monto']; } $precio_venta = (float)$precio_venta; $row['precio_venta_val'] = $precio_venta; $utilidad = $precio_venta - $precio_compra; $row['utilidad'] = $utilidad; if ($precio_compra > 0) { $row['rentabilidad'] = ($utilidad / $precio_compra) * 100; } else { $row['rentabilidad'] = 100; } } unset($row); $data['periodo'] = "General"; if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Creación Del $fecha_inicio al $fecha_fin"; } ob_start(); $this->views->getView('reportes', 'pdf_inventario', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'landscape'); $dompdf->render(); $dompdf->stream('Reporte_Inventario.pdf', array('Attachment' => false)); } public function generarVentas() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $vendedor = $_GET['vendedor'] ?? 'todos'; $cajero = $_GET['cajero'] ?? 'todos'; $data['ventas'] = $this->model->getVentasDetalleReporte($fecha_inicio, $fecha_fin, $vendedor, $cajero, $cliente, $this->id_sucursal); $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "Inicio al " . date('d/m/Y'); if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del " . date('d/m/Y', strtotime($fecha_inicio)) . " al " . date('d/m/Y', strtotime($fecha_fin)); } ob_start(); $this->views->getView('reportes', 'pdf_ventas', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'landscape'); $dompdf->render(); $dompdf->stream('Reporte_Ventas.pdf', array('Attachment' => false)); } public function generarApartados() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $logoPath = 'assets/images/logo.png'; if (file_exists($logoPath)) { $data['logo'] = 'data:image/png;base64,' . base64_encode(file_get_contents($logoPath)); } else { $data['logo'] = null; } $data['lista'] = $this->model->getApartados($fecha_inicio, $fecha_fin, $cliente, $estado, $this->id_sucursal); foreach ($data['lista'] as &$row) { $row['pendiente'] = (float)$row['total'] - (float)$row['abono']; $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Completado' : 'Pendiente'; } unset($row); $data['periodo'] = "Inicio al " . date('d/m/Y'); if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del $fecha_inicio al $fecha_fin"; } ob_start(); $this->views->getView('reportes', 'pdf_apartados', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'landscape'); $dompdf->render(); $dompdf->stream('Reporte_Apartados.pdf', array('Attachment' => false)); } public function generarSalidas() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $motivo = $_GET['motivo'] ?? ''; $data['salidas'] = $this->model->getSalidasInventario($fecha_inicio, $fecha_fin, $motivo, $this->id_sucursal); $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "Inicio al " . date('d/m/Y'); if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del $fecha_inicio al $fecha_fin"; } $this->renderPdf('pdf_salidas', $data, 'Reporte_Salidas.pdf'); } public function generarCompras() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $proveedor = $_GET['proveedor'] ?? 'todos'; $data['compras'] = $this->model->getCompras($fecha_inicio, $fecha_fin, $proveedor, $this->id_sucursal); foreach ($data['compras'] as &$row) { $row['situacion'] = (int)$row['estado'] === 1 ? 'Activa' : 'Anulada'; } unset($row); $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "General"; if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del $fecha_inicio al $fecha_fin"; } $this->renderPdf('pdf_compras', $data, 'Reporte_Compras.pdf'); } public function generarGastos() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $categoria = $_GET['categoria'] ?? 'todos'; $subcategoria = $_GET['subcategoria'] ?? 'todos'; $data['gastos'] = $this->model->getGastos($fecha_inicio, $fecha_fin, $categoria, $subcategoria, $this->id_sucursal); $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "General"; if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del $fecha_inicio al $fecha_fin"; } if ($categoria != 'todos') { $data['periodo'] .= " | Cat: $categoria"; } $this->renderPdf('pdf_gastos', $data, 'Reporte_Gastos.pdf', 'landscape'); } public function generarCuentasCobrar() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data['cuentas'] = $this->model->getCuentasCobrar($fecha_inicio, $fecha_fin, $cliente, $estado, $this->id_sucursal); foreach ($data['cuentas'] as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Pendiente' : 'Pagado'; } unset($row); $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "General"; if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del $fecha_inicio al $fecha_fin"; } $this->renderPdf('pdf_cuentas_cobrar', $data, 'Reporte_Cuentas_Cobrar.pdf', 'portrait'); } public function generarCuentasPagar() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $proveedor = $_GET['proveedor'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data['cuentas'] = $this->model->getCuentasPagar($fecha_inicio, $fecha_fin, $proveedor, $estado, $this->id_sucursal); foreach ($data['cuentas'] as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Pendiente' : 'Pagado'; } unset($row); $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "General"; if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del $fecha_inicio al $fecha_fin"; } $this->renderPdf('pdf_cuentas_pagar', $data, 'Reporte_Cuentas_Pagar.pdf', 'portrait'); } public function generarActivosFijos() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $estado = $_GET['estado'] ?? 'todos'; $data['activos'] = $this->model->getActivosFijos($fecha_inicio, $fecha_fin, $estado, $this->id_sucursal); foreach ($data['activos'] as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Activo' : 'Inactivo'; } unset($row); $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "General"; if ($fecha_inicio && $fecha_fin) { $data['periodo'] = "Del $fecha_inicio al $fecha_fin"; } $this->renderPdf('pdf_activos_fijos', $data, 'Reporte_Activo_Fijo.pdf', 'portrait'); } public function generarRentabilidadProductos() { $codigo = $_GET['codigo'] ?? ''; $nombre = $_GET['nombre'] ?? ''; $lista = $this->model->getRentabilidadProductos($codigo, $nombre, $this->id_sucursal); foreach ($lista as &$row) { $costo = (float)$row['precio_compra']; $preciosVentaArr = json_decode($row['precio_venta'], true); $venta = is_array($preciosVentaArr) && !empty($preciosVentaArr) ? (float)$preciosVentaArr[0]['monto'] : (float)$row['precio_venta']; $row['precio_venta'] = $venta; $utilidad = $venta - $costo; $porcentaje = $costo > 0 ? ($utilidad / $costo) * 100 : 100; $row['utilidad'] = $utilidad; $row['porcentaje_utilidad'] = $porcentaje; } unset($row); $data['lista'] = $lista; $data['empresa'] = $this->model->getEmpresa($this->id_sucursal); $data['periodo'] = "General"; if ($codigo) { $data['periodo'] .= " | Código: $codigo"; } if ($nombre) { $data['periodo'] .= " | Nombre: $nombre"; } $this->renderPdf('pdf_rentabilidad_productos', $data, 'Reporte_Rentabilidad_Productos.pdf', 'landscape'); } private function renderPdf($view, $data, $filename, $orientation = 'portrait') { ini_set('memory_limit', '4096M'); set_time_limit(0); ob_start(); $this->views->getView('reportes', $view, $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', $orientation); $dompdf->render(); $dompdf->stream($filename, array('Attachment' => false)); } public function generador() { $data['title'] = 'Generador de Códigos'; $data['script'] = 'generador.js'; $data['productos'] = $this->model->getProductosQRs($this->id_sucursal); $data['historial'] = $this->model->getHistorial($this->id_sucursal); $this->views->getView('reportes', 'generador', $data); } public function qrCode() { $texto = $_GET['texto'] ?? ''; if (trim($texto) === '') { $texto = 'Generador'; } try { $qrcode = new \chillerlan\QRCode\QRCode(); $dataUri = $qrcode->render($texto); if (ob_get_level() > 0) { ob_clean(); } if (strpos($dataUri, 'data:image/svg+xml;base64,') === 0) { $rawSvg = base64_decode(substr($dataUri, strlen('data:image/svg+xml;base64,'))); header('Content-Type: image/svg+xml'); echo $rawSvg; } else if (strpos($dataUri, 'data:image/png;base64,') === 0) { $rawPng = base64_decode(substr($dataUri, strlen('data:image/png;base64,'))); header('Content-Type: image/png'); echo $rawPng; } else { header('Content-Type: image/svg+xml'); echo $dataUri; } } catch (Exception $e) { if (ob_get_level() > 0) { ob_clean(); } header('Content-Type: image/svg+xml'); echo '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><text x="10" y="50" font-family="Arial" font-size="12" fill="red">Error QR</text></svg>'; } exit; } public function barcode() { $texto = $_GET['texto'] ?? ''; if (trim($texto) === '') { $texto = '000000'; } try { $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); if (ob_get_level() > 0) { ob_clean(); } header('Content-Type: image/png'); echo $generator->getBarcode($texto, $generator::TYPE_CODE_128, 2, 60); } catch (Exception $e) { try { $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); if (ob_get_level() > 0) { ob_clean(); } header('Content-Type: image/png'); $cleanText = preg_replace('/[^A-Za-z0-9]/', '', $texto); if ($cleanText === '') $cleanText = '000000'; echo $generator->getBarcode($cleanText, $generator::TYPE_CODE_128, 2, 60); } catch (Exception $ex) { if (ob_get_level() > 0) { ob_clean(); } header('Content-Type: image/png'); echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='); } } exit; } public function imprimirCodigo() { $tipo = $_GET['tipo'] ?? 'qr'; $texto = $_GET['texto'] ?? ''; $data['tipo'] = $tipo; $data['texto'] = $texto; $data['title'] = 'Imprimir Código'; $this->views->getView('reportes', 'print_codigo', $data); } public function obtenerCodigosBase64() { $tipo = $_POST['tipo'] ?? 'qr'; $estandar = $_POST['estandar'] ?? 'CODE128'; $res = ['status' => 'error', 'src' => '', 'texto' => '']; try { // Generar el valor del código automáticamente $texto = $this->generarValorCodigoUnico($tipo, $estandar); $res['texto'] = $texto; if ($tipo === 'qr') { $qrcode = new \chillerlan\QRCode\QRCode(); $res['src'] = $qrcode->render($texto); $res['status'] = 'success'; // Registrar en historial con cantidad 1 $this->model->registrarHistorial($tipo, $texto, 'N/A', 1, $this->id_usuario, $this->id_sucursal); } else { $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); $barcodeType = $generator::TYPE_CODE_128; if ($estandar === 'EAN13') $barcodeType = $generator::TYPE_EAN_13; elseif ($estandar === 'EAN8') $barcodeType = $generator::TYPE_EAN_8; elseif ($estandar === 'EAN5') $barcodeType = $generator::TYPE_EAN_5; elseif ($estandar === 'UPCA') $barcodeType = $generator::TYPE_UPC_A; elseif ($estandar === 'UPCE') $barcodeType = $generator::TYPE_UPC_E; $barcodeBase64 = base64_encode($generator->getBarcode($texto, $barcodeType, 2, 60)); $res['src'] = 'data:image/png;base64,' . $barcodeBase64; $res['status'] = 'success'; // Registrar en historial con cantidad 1 $this->model->registrarHistorial($tipo, $texto, $estandar, 1, $this->id_usuario, $this->id_sucursal); } } catch (Exception $e) { $res['message'] = $e->getMessage(); } echo json_encode($res); die(); } public function generarQrIndividual() { $id_producto = $_GET['id_producto'] ?? 0; if (empty($id_producto)) { echo "Producto no especificado."; die(); } $producto = $this->model->getProductoIndividualQR($id_producto, $this->id_sucursal); if (!$producto) { echo "Producto no encontrado."; die(); } $qrcode = new \chillerlan\QRCode\QRCode(); try { $textToEncode = !empty($producto['codigo']) ? $producto['codigo'] : '000000'; $producto['qr_base64'] = $qrcode->render($textToEncode); } catch (Exception $e) { $producto['qr_base64'] = ''; } $data['producto'] = $producto; $data['title'] = 'Etiqueta QR Individual'; ob_start(); $this->views->getView('reportes', 'pdf_qr_individual', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('letter', 'portrait'); $dompdf->render(); $filename = 'QR_Individual_' . preg_replace('/[^A-Za-z0-9]/', '_', $producto['descripcion']) . '.pdf'; $dompdf->stream($filename, array('Attachment' => false)); } public function generarQrCatalogo() { $productos = $this->model->getProductosQRs($this->id_sucursal); $qrcode = new \chillerlan\QRCode\QRCode(); foreach ($productos as &$p) { try { $textToEncode = !empty($p['codigo']) ? $p['codigo'] : '000000'; $p['qr_base64'] = $qrcode->render($textToEncode); } catch (Exception $e) { $p['qr_base64'] = ''; } } $data['productos'] = $productos; $data['title'] = 'Catálogo de Códigos QR'; $empresa = $this->model->getEmpresa($this->id_sucursal); $data['sucursal'] = $empresa['nombre'] ?? 'Principal'; ob_start(); $this->views->getView('reportes', 'pdf_qr_catalogo', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'portrait'); $dompdf->render(); $dompdf->stream('Catalogo_QR.pdf', array('Attachment' => false)); } public function generarPdfPersonalizado() { $tipo = $_GET['tipo'] ?? 'qr'; $cantidad = (int)($_GET['cantidad'] ?? 1); $estandar = $_GET['estandar'] ?? 'CODE128'; $texto_input = $_GET['texto'] ?? ''; $codigos = []; $qrcode = null; $generator = null; $barcodeType = null; if ($tipo === 'qr') { $qrcode = new \chillerlan\QRCode\QRCode(); } else { $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); $barcodeType = $generator::TYPE_CODE_128; if ($estandar === 'EAN13') $barcodeType = $generator::TYPE_EAN_13; elseif ($estandar === 'EAN8') $barcodeType = $generator::TYPE_EAN_8; elseif ($estandar === 'EAN5') $generator = $generator::TYPE_EAN_5; elseif ($estandar === 'UPCA') $barcodeType = $generator::TYPE_UPC_A; elseif ($estandar === 'UPCE') $barcodeType = $generator::TYPE_UPC_E; } for ($i = 0; $i < $cantidad; $i++) { $texto = $texto_input; $es_auto = false; if (trim($texto) === '') { // Generar valor único de forma automática $texto = $this->generarValorCodigoUnico($tipo, $estandar); $es_auto = true; } if ($es_auto) { // Registrar en historial cada código único con cantidad 1 $this->model->registrarHistorial($tipo, $texto, ($tipo === 'qr' ? 'N/A' : $estandar), 1, $this->id_usuario, $this->id_sucursal); } else { if ($i === 0) { // Si el código es manual, se registra solo una vez con la cantidad total $this->model->registrarHistorial($tipo, $texto, ($tipo === 'qr' ? 'N/A' : $estandar), $cantidad, $this->id_usuario, $this->id_sucursal); } } $src = ''; if ($tipo === 'qr') { try { $src = $qrcode->render($texto); } catch (Exception $e) { $src = ''; } } else { try { $barcodeBase64 = base64_encode($generator->getBarcode($texto, $barcodeType, 2, 60)); $src = 'data:image/png;base64,' . $barcodeBase64; } catch (Exception $e) { echo "Error al generar código de barras: " . htmlspecialchars($e->getMessage()); die(); } } $codigos[] = [ 'texto' => $texto, 'img_src' => $src ]; } $data['tipo'] = $tipo; $data['estandar'] = $estandar; $data['cantidad'] = $cantidad; $data['codigos'] = $codigos; $data['title'] = 'Impresión de Códigos'; ob_start(); $this->views->getView('reportes', 'pdf_generado_personalizado', $data); $html = ob_get_clean(); $dompdf = new Dompdf(); $options = $dompdf->getOptions(); $options->set('isJavascriptEnabled', true); $options->set('isRemoteEnabled', true); $dompdf->setOptions($options); $dompdf->loadHtml($html); $dompdf->setPaper('letter', 'portrait'); $dompdf->render(); $primer_texto = !empty($codigos) ? $codigos[0]['texto'] : 'Varios'; $filename = 'Codigos_' . $tipo . '_' . preg_replace('/[^A-Za-z0-9]/', '_', $primer_texto) . '.pdf'; $dompdf->stream($filename, array('Attachment' => false)); } private function generarValorCodigoUnico($tipo, $estandar) { $maxAttempts = 50; $attempt = 0; do { $val = ''; if ($tipo === 'qr') { // Generar un número de 10 dígitos único para QR for ($i = 0; $i < 10; $i++) { $val .= rand(0, 9); } } else { if ($estandar === 'EAN13') { $digits12 = ''; for ($i = 0; $i < 12; $i++) { $digits12 .= rand(0, 9); } $sum = 0; for ($i = 0; $i < 12; $i++) { $sum += (int)$digits12[$i] * ($i % 2 === 0 ? 1 : 3); } $mod = $sum % 10; $checksum = ($mod === 0) ? 0 : 10 - $mod; $val = $digits12 . $checksum; } elseif ($estandar === 'EAN8') { $digits7 = ''; for ($i = 0; $i < 7; $i++) { $digits7 .= rand(0, 9); } $sum = 0; for ($i = 0; $i < 7; $i++) { $sum += (int)$digits7[$i] * ($i % 2 === 0 ? 3 : 1); } $mod = $sum % 10; $checksum = ($mod === 0) ? 0 : 10 - $mod; $val = $digits7 . $checksum; } elseif ($estandar === 'UPCA') { $digits11 = ''; for ($i = 0; $i < 11; $i++) { $digits11 .= rand(0, 9); } $sum = 0; for ($i = 0; $i < 11; $i++) { $sum += (int)$digits11[$i] * ($i % 2 === 0 ? 3 : 1); } $mod = $sum % 10; $checksum = ($mod === 0) ? 0 : 10 - $mod; $val = $digits11 . $checksum; } elseif ($estandar === 'UPCE') { // UPC-E necesita 6 dígitos for ($i = 0; $i < 6; $i++) { $val .= rand(0, 9); } } elseif ($estandar === 'EAN5') { // EAN-5 necesita 5 dígitos for ($i = 0; $i < 5; $i++) { $val .= rand(0, 9); } } else { // CODE-128 for ($i = 0; $i < 10; $i++) { $val .= rand(0, 9); } } } // Validar que no exista en el historial o en productos $checkHistorial = $this->model->select("SELECT id FROM historial_codigos WHERE valor = '$val'"); $checkProductos = $this->model->select("SELECT id FROM productos WHERE codigo = '$val'"); $attempt++; } while ((!empty($checkHistorial) || !empty($checkProductos)) && $attempt < $maxAttempts); return $val; } // ========================================== // MÉTODOS PARA EXPORTACIÓN A EXCEL (CONTADURÍA) // ========================================== public function excelVentas() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $vendedor = $_GET['vendedor'] ?? 'todos'; $cajero = $_GET['cajero'] ?? 'todos'; $data = $this->model->getVentasDetalleReporte($fecha_inicio, $fecha_fin, $vendedor, $cajero, $cliente, $this->id_sucursal); $period = "Inicio al " . date('d/m/Y'); if ($fecha_inicio && $fecha_fin) { $period = "Del " . date('d/m/Y', strtotime($fecha_inicio)) . " al " . date('d/m/Y', strtotime($fecha_fin)); } $headers = ["CODIGO", "CATEGORIA", "PRODUCTO", "CLIENTE", "# DE FACTURA", "FORMA DE PAGO", "PRECIO COSTO", "PRECIO VENTA", "UTILIDAD C$", "PORCENTAJE DE UTILIDAD"]; $columns_map = ["codigo", "categoria", "producto", "cliente", "factura", "forma_pago", "precio_costo", "precio_venta", "utilidad", "porcentaje_utilidad"]; $formats = [ "precio_costo" => "currency", "precio_venta" => "currency", "utilidad" => "currency", "porcentaje_utilidad" => "number" ]; $totals = ["precio_costo" => true, "precio_venta" => true, "utilidad" => true]; $this->exportToExcel("Reporte_Ventas.xlsx", "Historial de Ventas Detallado", $period, $headers, $data, $columns_map, $formats, $totals); } public function excelApartados() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $lista = $this->model->getApartados($fecha_inicio, $fecha_fin, $cliente, $estado, $this->id_sucursal); foreach ($lista as &$row) { $row['pendiente'] = (float)$row['total'] - (float)$row['abono']; $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Completado' : 'Pendiente'; } unset($row); $spreadsheet = new Spreadsheet(); $spreadsheet->getProperties() ->setCreator($_SESSION['nombre_usuario']) ->setTitle("Reporte de Apartados"); $spreadsheet->setActiveSheetIndex(0); $hojaActiva = $spreadsheet->getActiveSheet(); // Anchos de columna $hojaActiva->getColumnDimension('A')->setWidth(20); $hojaActiva->getColumnDimension('B')->setWidth(30); $hojaActiva->getColumnDimension('C')->setWidth(15); $hojaActiva->getColumnDimension('D')->setWidth(15); $hojaActiva->getColumnDimension('E')->setWidth(15); $hojaActiva->getColumnDimension('F')->setWidth(15); $hojaActiva->getColumnDimension('G')->setWidth(15); // Estilos de cabecera $spreadsheet->getActiveSheet()->getStyle('A1:G1')->getFill() ->setFillType(Fill::FILL_SOLID) ->getStartColor()->setARGB('008cff'); $spreadsheet->getActiveSheet()->getStyle('A1:G1') ->getFont()->getColor()->setARGB(Color::COLOR_WHITE); $hojaActiva->setCellValue('A1', 'FECHA CREACIÓN'); $hojaActiva->setCellValue('B1', 'CLIENTE'); $hojaActiva->setCellValue('C1', 'TELÉFONO'); $hojaActiva->setCellValue('D1', 'TOTAL'); $hojaActiva->setCellValue('E1', 'ABONADO'); $hojaActiva->setCellValue('F1', 'PENDIENTE'); $hojaActiva->setCellValue('G1', 'ESTADO'); $fila = 2; foreach ($lista as $row) { $hojaActiva->setCellValue('A' . $fila, $row['fecha_create']); $hojaActiva->setCellValue('B' . $fila, $row['cliente']); $hojaActiva->setCellValue('C' . $fila, $row['telefono']); $hojaActiva->setCellValue('D' . $fila, number_format((float)$row['total'], 2, '.', '')); $hojaActiva->setCellValue('E' . $fila, number_format((float)$row['abono'], 2, '.', '')); $hojaActiva->setCellValue('F' . $fila, number_format((float)$row['pendiente'], 2, '.', '')); $hojaActiva->setCellValue('G' . $fila, $row['estado_lbl']); $fila++; } header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="Reporte_Apartados.xlsx"'); $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output'); } public function excelInventario() { // Aumentar límite de memoria y tiempo ilimitado para Excel muy grandes ini_set('memory_limit', '4096M'); set_time_limit(0); $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $categoria = $_GET['categoria'] ?? 'todos'; $bodega = $_GET['bodega'] ?? 'todos'; $vencimiento = $_GET['vencimiento'] ?? ''; $lista = $this->model->getInventario($fecha_inicio, $fecha_fin, $categoria, $bodega, $vencimiento, $this->id_sucursal); foreach ($lista as &$row) { $es_servicio = (int)($row['servicio'] ?? 0) === 1; $has_lote = isset($row['lote_id']) && $row['lote_id'] !== null; $stock = $es_servicio ? 0 : ($has_lote ? (float)$row['lote_cantidad'] : (float)($row['cantidad'] ?? 0)); $row['stock_numeric'] = $stock; $row['fecha_venc'] = $es_servicio ? 'N/A' : ($has_lote ? $row['lote_fecha'] : ($row['fecha_vencimiento'] ?? 'N/A')); $precio_compra = (float)$row['precio_compra']; $row['total_inversion'] = $es_servicio ? 0.0 : ($precio_compra * $stock); $precio_venta = $row['precio_venta']; $preciosVentaArr = json_decode($precio_venta, true); if (is_array($preciosVentaArr) && count($preciosVentaArr) > 0) { $precio_venta = $preciosVentaArr[0]['monto']; } $precio_venta = (float)$precio_venta; $row['precio_venta_val'] = $precio_venta; $utilidad = $precio_venta - $precio_compra; $row['utilidad'] = $utilidad; if ($precio_compra > 0) { $row['rentabilidad'] = ($utilidad / $precio_compra) * 100; } else { $row['rentabilidad'] = 100; } } unset($row); $spreadsheet = new Spreadsheet(); $spreadsheet->getProperties() ->setCreator($_SESSION['nombre_usuario']) ->setTitle("Reporte de Inventarios"); $spreadsheet->setActiveSheetIndex(0); $hojaActiva = $spreadsheet->getActiveSheet(); // Anchos de columna $hojaActiva->getColumnDimension('A')->setWidth(15); $hojaActiva->getColumnDimension('B')->setWidth(20); $hojaActiva->getColumnDimension('C')->setWidth(20); $hojaActiva->getColumnDimension('D')->setWidth(35); $hojaActiva->getColumnDimension('E')->setWidth(10); $hojaActiva->getColumnDimension('F')->setWidth(15); $hojaActiva->getColumnDimension('G')->setWidth(15); $hojaActiva->getColumnDimension('H')->setWidth(15); $hojaActiva->getColumnDimension('I')->setWidth(15); $hojaActiva->getColumnDimension('J')->setWidth(15); $hojaActiva->getColumnDimension('K')->setWidth(15); // Estilos de cabecera $spreadsheet->getActiveSheet()->getStyle('A1:K1')->getFill() ->setFillType(Fill::FILL_SOLID) ->getStartColor()->setARGB('008cff'); $spreadsheet->getActiveSheet()->getStyle('A1:K1') ->getFont()->getColor()->setARGB(Color::COLOR_WHITE); $hojaActiva->setCellValue('A1', 'CÓDIGO'); $hojaActiva->setCellValue('B1', 'CATEGORÍA'); $hojaActiva->setCellValue('C1', 'BODEGA'); $hojaActiva->setCellValue('D1', 'PRODUCTO'); $hojaActiva->setCellValue('E1', 'STOCK'); $hojaActiva->setCellValue('F1', 'PRECIO COSTO'); $hojaActiva->setCellValue('G1', 'TOTAL INVERSIÓN'); $hojaActiva->setCellValue('H1', 'PRECIO VENTA'); $hojaActiva->setCellValue('I1', 'UTILIDAD C$'); $hojaActiva->setCellValue('J1', 'RENTABILIDAD'); $hojaActiva->setCellValue('K1', 'VENCIMIENTO'); $fila = 2; foreach ($lista as $row) { $hojaActiva->setCellValue('A' . $fila, $row['codigo']); $hojaActiva->setCellValue('B' . $fila, $row['nombre_categoria']); $hojaActiva->setCellValue('C' . $fila, $row['bodega']); $hojaActiva->setCellValue('D' . $fila, $row['descripcion']); $hojaActiva->setCellValue('E' . $fila, $row['stock_numeric']); $hojaActiva->setCellValue('F' . $fila, number_format((float)$row['precio_compra'], 2, '.', '')); $hojaActiva->setCellValue('G' . $fila, number_format((float)$row['total_inversion'], 2, '.', '')); $hojaActiva->setCellValue('H' . $fila, number_format((float)$row['precio_venta_val'], 2, '.', '')); $hojaActiva->setCellValue('I' . $fila, number_format((float)$row['utilidad'], 2, '.', '')); $hojaActiva->setCellValue('J' . $fila, number_format((float)$row['rentabilidad'], 2, '.', '') . '%'); $hojaActiva->setCellValue('K' . $fila, $row['fecha_venc']); $fila++; } header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="Reporte_Inventario.xlsx"'); $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output'); } public function excelSalidas() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $motivo = $_GET['motivo'] ?? ''; $data = $this->model->getSalidasInventario($fecha_inicio, $fecha_fin, $motivo, $this->id_sucursal); $period = "Inicio al " . date('d/m/Y'); if ($fecha_inicio && $fecha_fin) { $period = "Del $fecha_inicio al $fecha_fin"; } $headers = ["FECHA", "PRODUCTO", "CÓDIGO", "USUARIO", "CANTIDAD", "MOTIVO"]; $columns_map = ["fecha", "producto", "codigo", "usuario", "cantidad", "motivo"]; $formats = [ "fecha" => "date", "cantidad" => "integer" ]; $totals = ["cantidad" => true]; $this->exportToExcel("Reporte_Salidas.xlsx", "Salidas de Inventario", $period, $headers, $data, $columns_map, $formats, $totals); } public function excelCompras() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $proveedor = $_GET['proveedor'] ?? 'todos'; $data = $this->model->getCompras($fecha_inicio, $fecha_fin, $proveedor, $this->id_sucursal); foreach ($data as &$row) { $row['situacion'] = (int)$row['estado'] === 1 ? 'Activa' : 'Anulada'; } unset($row); $period = "General"; if ($fecha_inicio && $fecha_fin) { $period = "Del $fecha_inicio al $fecha_fin"; } $headers = ["FECHA", "PROVEEDOR", "USUARIO", "SERIE / DOC", "MÉTODO", "TOTAL", "SITUACIÓN"]; $columns_map = ["fecha", "proveedor", "usuario", "serie", "metodo", "total", "situacion"]; $formats = [ "fecha" => "date", "total" => "currency" ]; $totals = ["total" => true]; $this->exportToExcel("Reporte_Compras.xlsx", "Compras", $period, $headers, $data, $columns_map, $formats, $totals); } public function excelGastos() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $categoria = $_GET['categoria'] ?? 'todos'; $subcategoria = $_GET['subcategoria'] ?? 'todos'; $data = $this->model->getGastos($fecha_inicio, $fecha_fin, $categoria, $subcategoria, $this->id_sucursal); $period = "General"; if ($fecha_inicio && $fecha_fin) { $period = "Del $fecha_inicio al $fecha_fin"; } $headers = ["FECHA", "NO DOC", "CATEGORIA", "SUBCATEGORIA", "DESCRIPCION", "USUARIO", "MONTO", "IVA", "TOTAL"]; $columns_map = ["fecha", "id", "categoria_nombre", "subcategoria", "descripcion", "usuario", "subtotal", "iva_monto", "monto"]; $formats = [ "fecha" => "date", "subtotal" => "currency", "iva_monto" => "currency", "monto" => "currency" ]; $totals = [ "subtotal" => true, "iva_monto" => true, "monto" => true ]; $this->exportToExcel("Reporte_Gastos.xlsx", "Gastos", $period, $headers, $data, $columns_map, $formats, $totals); } public function excelCuentasCobrar() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $cliente = $_GET['cliente'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data = $this->model->getCuentasCobrar($fecha_inicio, $fecha_fin, $cliente, $estado, $this->id_sucursal); foreach ($data as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Pendiente' : 'Pagado'; } unset($row); $period = "General"; if ($fecha_inicio && $fecha_fin) { $period = "Del $fecha_inicio al $fecha_fin"; } $headers = ["FECHA", "SERIE VENTA", "CLIENTE", "MONTO CRÉDITO", "ABONADO", "RESTANTE", "ESTADO"]; $columns_map = ["fecha_venta", "serie", "cliente", "monto", "abono", "restante", "estado_lbl"]; $formats = [ "fecha_venta" => "date", "monto" => "currency", "abono" => "currency", "restante" => "currency" ]; $totals = [ "monto" => true, "abono" => true, "restante" => true ]; $this->exportToExcel("Reporte_Cuentas_Cobrar.xlsx", "Cuentas por Cobrar", $period, $headers, $data, $columns_map, $formats, $totals); } public function excelCuentasPagar() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $proveedor = $_GET['proveedor'] ?? 'todos'; $estado = $_GET['estado'] ?? 'todos'; $data = $this->model->getCuentasPagar($fecha_inicio, $fecha_fin, $proveedor, $estado, $this->id_sucursal); foreach ($data as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Pendiente' : 'Pagado'; } unset($row); $period = "General"; if ($fecha_inicio && $fecha_fin) { $period = "Del $fecha_inicio al $fecha_fin"; } $headers = ["FECHA", "SERIE COMPRA", "PROVEEDOR", "MONTO DEUDA", "ABONADO", "RESTANTE", "ESTADO"]; $columns_map = ["fecha_compra", "serie", "proveedor", "monto", "abono", "restante", "estado_lbl"]; $formats = [ "fecha_compra" => "date", "monto" => "currency", "abono" => "currency", "restante" => "currency" ]; $totals = [ "monto" => true, "abono" => true, "restante" => true ]; $this->exportToExcel("Reporte_Cuentas_Pagar.xlsx", "Cuentas por Pagar", $period, $headers, $data, $columns_map, $formats, $totals); } public function excelActivosFijos() { $fecha_inicio = $_GET['desde'] ?? ''; $fecha_fin = $_GET['hasta'] ?? ''; $estado = $_GET['estado'] ?? 'todos'; $data = $this->model->getActivosFijos($fecha_inicio, $fecha_fin, $estado, $this->id_sucursal); foreach ($data as &$row) { $row['estado_lbl'] = (int)$row['estado'] === 1 ? 'Activo' : 'Inactivo'; } unset($row); $period = "General"; if ($fecha_inicio && $fecha_fin) { $period = "Del $fecha_inicio al $fecha_fin"; } $headers = ["CÓDIGO", "DESCRIPCIÓN", "FECHA ADQ.", "VALOR", "ESTADO"]; $columns_map = ["codigo", "descripcion", "fecha_compra", "costo", "estado_lbl"]; $formats = [ "fecha_compra" => "date", "costo" => "currency" ]; $totals = [ "costo" => true ]; $this->exportToExcel("Reporte_Activo_Fijo.xlsx", "Activo Fijo", $period, $headers, $data, $columns_map, $formats, $totals); } public function excelRentabilidadProductos() { $codigo = $_GET['codigo'] ?? ''; $nombre = $_GET['nombre'] ?? ''; $data = $this->model->getRentabilidadProductos($codigo, $nombre, $this->id_sucursal); foreach ($data as &$row) { $costo = (float)$row['precio_compra']; $preciosVentaArr = json_decode($row['precio_venta'], true); $venta = is_array($preciosVentaArr) && !empty($preciosVentaArr) ? (float)$preciosVentaArr[0]['monto'] : (float)$row['precio_venta']; $row['precio_venta'] = $venta; $utilidad = $venta - $costo; $porcentaje = $costo > 0 ? ($utilidad / $costo) * 100 : 100; $row['utilidad'] = $utilidad; $row['porcentaje_utilidad'] = number_format($porcentaje, 2) . '%'; } unset($row); $period = "General"; if ($codigo) { $period .= " | Código: $codigo"; } if ($nombre) { $period .= " | Nombre: $nombre"; } $headers = ["CÓDIGO", "CATEGORÍA", "PRODUCTO", "PRECIO COSTO", "PRECIO VENTA", "UTILIDAD C$", "% UTILIDAD"]; $columns_map = ["codigo", "categoria", "producto", "precio_compra", "precio_venta", "utilidad", "porcentaje_utilidad"]; $formats = [ "precio_compra" => "currency", "precio_venta" => "currency", "utilidad" => "currency" ]; $totals = [ "precio_compra" => true, "precio_venta" => true, "utilidad" => true ]; $this->exportToExcel("Reporte_Rentabilidad_Productos.xlsx", "Rentabilidad por Producto", $period, $headers, $data, $columns_map, $formats, $totals); } private function exportToExcel($filename, $title, $period, $headers, $data, $columns_map, $formats = [], $totals = []) { ini_set('memory_limit', '4096M'); set_time_limit(0); $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Title Block $sheet->setCellValue('A1', strtoupper($title)); $sheet->getStyle('A1')->getFont()->setBold(true)->setSize(16); if (!empty($period)) { $sheet->setCellValue('A2', 'Periodo: ' . $period); $sheet->getStyle('A2')->getFont()->setItalic(true)->setSize(11); $startRow = 4; } else { $startRow = 3; } // Headers $colIndex = 'A'; foreach ($headers as $header) { $sheet->setCellValue($colIndex . $startRow, $header); $sheet->getStyle($colIndex . $startRow)->getFont()->setBold(true)->setColor(new \PhpOffice\PhpSpreadsheet\Style\Color(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE)); $sheet->getStyle($colIndex . $startRow)->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('1F4E78'); // Dark Blue $sheet->getStyle($colIndex . $startRow)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); $colIndex++; } $currentRow = $startRow + 1; $totalsData = array_fill_keys(array_keys($totals), 0.0); // Data Rows foreach ($data as $row) { $colIndex = 'A'; foreach ($columns_map as $key) { $val = $row[$key] ?? ''; $format = $formats[$key] ?? 'text'; if ($format === 'currency') { $sheet->setCellValue($colIndex . $currentRow, (float)$val); $sheet->getStyle($colIndex . $currentRow)->getNumberFormat()->setFormatCode('"' . MONEDA . '"#,##0.00'); $sheet->getStyle($colIndex . $currentRow)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT); } elseif ($format === 'decimal') { $sheet->setCellValue($colIndex . $currentRow, (float)$val); $sheet->getStyle($colIndex . $currentRow)->getNumberFormat()->setFormatCode('#,##0.00'); $sheet->getStyle($colIndex . $currentRow)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT); } elseif ($format === 'integer') { $sheet->setCellValue($colIndex . $currentRow, (int)$val); $sheet->getStyle($colIndex . $currentRow)->getNumberFormat()->setFormatCode('#,##0'); $sheet->getStyle($colIndex . $currentRow)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); } elseif ($format === 'date') { $sheet->setCellValue($colIndex . $currentRow, !empty($val) ? date('d/m/Y', strtotime($val)) : ''); $sheet->getStyle($colIndex . $currentRow)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); } else { $sheet->setCellValue($colIndex . $currentRow, $val); } if (isset($totals[$key])) { $totalsData[$key] += (float)$val; } $colIndex++; } $currentRow++; } // Totals Row if (!empty($totals)) { $colIndex = 'A'; $sheet->setCellValue('A' . $currentRow, 'TOTAL'); $sheet->getStyle('A' . $currentRow)->getFont()->setBold(true); foreach ($columns_map as $key) { if (isset($totals[$key])) { $sheet->setCellValue($colIndex . $currentRow, $totalsData[$key]); $sheet->getStyle($colIndex . $currentRow)->getFont()->setBold(true); $format = $formats[$key] ?? 'text'; if ($format === 'currency') { $sheet->getStyle($colIndex . $currentRow)->getNumberFormat()->setFormatCode('"' . MONEDA . '"#,##0.00'); } elseif ($format === 'decimal') { $sheet->getStyle($colIndex . $currentRow)->getNumberFormat()->setFormatCode('#,##0.00'); } elseif ($format === 'integer') { $sheet->getStyle($colIndex . $currentRow)->getNumberFormat()->setFormatCode('#,##0'); } } $colIndex++; } $lastCol = chr(ord('A') + count($headers) - 1); $sheet->getStyle('A' . $currentRow . ':' . $lastCol . $currentRow)->getBorders()->getBottom()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_DOUBLE); $sheet->getStyle('A' . $currentRow . ':' . $lastCol . $currentRow)->getBorders()->getTop()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN); } // Borders $lastCol = chr(ord('A') + count($headers) - 1); $range = 'A' . $startRow . ':' . $lastCol . ($currentRow); $sheet->getStyle($range)->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN); // Autofit columns $colIndex = 'A'; for ($i = 0; $i < count($headers); $i++) { $sheet->getColumnDimension($colIndex)->setAutoSize(true); $colIndex++; } header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="' . $filename . '"'); header('Cache-Control: max-age=0'); $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet); $writer->save('php://output'); exit; } } ?>
Coded With 💗 by
0x6ick