diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php
index 9ddf7463..41530954 100644
--- a/ci4/app/Config/Routes.php
+++ b/ci4/app/Config/Routes.php
@@ -700,6 +700,15 @@ $routes->group(
}
);
+$routes->group(
+ 'print-factura',
+ ['namespace' => 'App\Controllers\Pdf'],
+ function ($routes) {
+ $routes->get('index/(:num)', 'PrintFacturas::index/$1', ['as' => 'viewFacturaPDF']);
+ $routes->get('generar/(:num)', 'PrintFacturas::generar/$1', ['as' => 'facturaToPdf']);
+ }
+);
+
$routes->group(
'export-giros',
['namespace' => 'App\Controllers\Excel'],
diff --git a/ci4/app/Controllers/Pdf/PrintFacturas.php b/ci4/app/Controllers/Pdf/PrintFacturas.php
new file mode 100644
index 00000000..08e6e230
--- /dev/null
+++ b/ci4/app/Controllers/Pdf/PrintFacturas.php
@@ -0,0 +1,65 @@
+getResourceForPdf($id_factura)->get()->getRow();
+ $data['lineas_factura'] = $lineasFacturaModel->getResourceForPdf($id_factura)->get()->getResultObject();
+ $data['resumen_por_iva'] = $lineasFacturaModel->getResourceResumenIVAsForPdf($id_factura)->get()->getResultObject();
+
+ return view(getenv('theme.path') . 'pdfs/factura', $data);
+ }
+
+ public function generar($id_factura)
+ {
+
+ // Cargar modelos
+ $facturaModel = model('App\Models\Facturas\FacturaModel');
+ $lineasFacturaModel = model('App\Models\Facturas\FacturaLineaModel');
+
+ // Informacion del presupuesto
+ $data['factura'] = $facturaModel->getResourceForPdf($id_factura)->get()->getRow();
+ $data['lineas_factura'] = $lineasFacturaModel->getResourceForPdf($id_factura)->get()->getResultObject();
+ $data['resumen_por_iva'] = $lineasFacturaModel->getResourceResumenIVAsForPdf($id_factura)->get()->getResultObject();
+
+ // Crear una instancia de Dompdf
+ $options = new \Dompdf\Options();
+ $options->set('isHtml5ParserEnabled', true);
+ $options->set('isPhpEnabled', true);
+ $options->set('isRemoteEnabled', true);
+ $dompdf = new \Dompdf\Dompdf($options);
+
+ // Contenido HTML del documento
+ $dompdf->loadHtml(view(getenv('theme.path').'pdfs/factura', $data));
+
+ // Establecer el tamaño del papel
+ $dompdf->setPaper('A4', 'portrait');
+
+ // Renderizar el PDF
+ $dompdf->render();
+
+ // Obtener el contenido generado
+ $output = $dompdf->output();
+
+ // Establecer las cabeceras para visualizar en lugar de descargar
+ $file_name = $data['factura']->numero . ".pdf";
+ return $this->response
+ ->setStatusCode(200)
+ ->setHeader('Content-Type', 'application/pdf')
+ ->setHeader('Content-Disposition', 'inline; filename="' . $file_name . '"')
+ ->setHeader('Cache-Control', 'private, max-age=0, must-revalidate')
+ ->setHeader('Pragma', 'public')
+ ->setHeader('Content-Length', strlen($output))
+ ->setBody($output);
+ }
+}
\ No newline at end of file
diff --git a/ci4/app/Models/Facturas/FacturaLineaModel.php b/ci4/app/Models/Facturas/FacturaLineaModel.php
index b808ac8c..b1bd1d9f 100644
--- a/ci4/app/Models/Facturas/FacturaLineaModel.php
+++ b/ci4/app/Models/Facturas/FacturaLineaModel.php
@@ -54,6 +54,56 @@ class FacturaLineaModel extends \App\Models\BaseModel {
return $builder;
}
+
+ public function getResourceResumenIVAsForPdf($factura_id = -1)
+ {
+ $builder = $this->db
+ ->table($this->table . " t1")
+ ->select(
+ "t1.iva,
+ ROUND(SUM(t1.base), 2) AS base,
+ ROUND(SUM(t1.total_iva), 2) AS total_iva,
+ ROUND(SUM(t1.total), 2) AS total"
+ )
+ ->where("t1.factura_id", $factura_id)
+ ->groupBy('t1.iva')
+ ->orderBy('t1.iva', 'ASC'); // Ordena por iva en forma ascendente
+
+ return $builder;
+ }
+
+
+ /**
+ * Get resource data for creating PDFs.
+ *
+ * @param string $search
+ *
+ * @return \CodeIgniter\Database\BaseBuilder
+ */
+ public function getResourceForPdf($factura_id = -1)
+ {
+ $builder = $this->db
+ ->table($this->table . " t1")
+ ->select(
+ "t1.id AS id, t1.factura_id AS factura_id,
+ t1.pedido_linea_impresion_id AS pedido_linea_impresion_id, t1.pedido_maquetacion_id AS pedido_maquetacion_id,
+ t1.descripcion AS descripcion, t1.cantidad as cantidad, t1.precio_unidad AS precio_unidad, t1.iva AS iva,
+ t1.base AS base, t1.total_iva AS total_iva, t1.total AS total, t1.data AS data, t2.pedido_id AS pedido_id,
+ t3.total_aceptado AS total_aceptado, t4.tirada_flexible AS tirada_flexible, t4.descuento_tirada_flexible AS descuento_tirada_flexible,
+ t6.cantidad AS cantidad_albaran"
+ )
+ ->join("pedidos_linea t2", "t2.id = t1.pedido_linea_impresion_id", "left")
+ ->join("presupuestos t3", "t3.id = t2.presupuesto_id", "left")
+ ->join("clientes t4", "t4.id = t3.cliente_id", "left")
+ ->join("albaranes t5", "t5.pedido_id = t2.pedido_id", "left")
+ ->join("albaranes_lineas t6", "t6.albaran_id = t5.id", "left")
+ ->where("t1.factura_id", $factura_id)
+ ->where("t1.deleted_at", null);
+
+ return $builder;
+ }
+
+
public function addFacturaPedidoLinea($factura_id, $pedido_linea_id, $cantidad)
{
$data = [
diff --git a/ci4/app/Models/Facturas/FacturaModel.php b/ci4/app/Models/Facturas/FacturaModel.php
index ccdf7f43..aeb8e46c 100644
--- a/ci4/app/Models/Facturas/FacturaModel.php
+++ b/ci4/app/Models/Facturas/FacturaModel.php
@@ -102,6 +102,40 @@ class FacturaModel extends \App\Models\BaseModel {
}
+ /**
+ * Get resource data for creating PDFs.
+ *
+ * @param string $search
+ *
+ * @return \CodeIgniter\Database\BaseBuilder
+ */
+ public function getResourceForPdf($factura_id = -1)
+ {
+ $builder = $this->db
+ ->table($this->table . " t1")
+ ->select(
+ "t1.id AS id, t1.numero AS numero, DATE_FORMAT(t1.fecha_factura_at, '%d/%m/%Y') AS fecha_factura_at,
+ t1.base AS base, t1.total AS total, t1.pendiente AS pendiente,
+ t1.creditoAsegurado AS creditoAsegurado, t1.estado AS estado, t1.estado_pago AS estado_pago,
+ t4.nombre AS forma_pago,
+ DATE_FORMAT(MIN(CASE WHEN t3.fecha_vencimiento_at != '0000-00-00 00:00:00' THEN t3.fecha_vencimiento_at ELSE NULL END), '%d/%m/%Y') AS vencimiento,
+ t2.nombre AS cliente, t2.direccion AS cliente_direccion, t2.ciudad AS cliente_ciudad,
+ t2.cp AS cliente_cp, t2.cif AS cliente_cif, t2.vencimiento AS dias_vencimiento, t2.ccc AS cliente_ccc,
+ t5.nombre AS cliente_pais"
+ );
+
+ $builder->join("clientes t2", "t2.id = t1.cliente_id", "left");
+ $builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left");
+ $builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left");
+ $builder->join("lg_paises t5", "t2.pais_id = t5.id", "left");
+
+ $builder->where("t1.deleted_at IS NULL");
+ $builder->groupBy("t1.id"); // Agrupa por id de la factura
+
+ return $builder;
+ }
+
+
public function getResourcePedidos($pedido_id)
{
$builder = $this->db
diff --git a/ci4/app/Views/themes/vuexy/pdfs/factura.php b/ci4/app/Views/themes/vuexy/pdfs/factura.php
new file mode 100644
index 00000000..55a05982
--- /dev/null
+++ b/ci4/app/Views/themes/vuexy/pdfs/factura.php
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+ | FACTURA Nº: |
+ = ($factura->estado == 'draft') ? 'BORRADOR' : $factura->numero ?> |
+ FECHA: |
+ = $factura->fecha_factura_at ?> |
+
+
+
+
+ | Dirección: |
+
+
+ | Persona de contacto: |
+ = $factura->cliente_direccion ?> |
+
+
+ | Razón social: = $factura->cliente ?>
+ |
+ = $factura->cliente_cp ?>
+ , = $factura->cliente_ciudad ?> |
+
+
+ | CIF: = $factura->cliente_cif ?> |
+ = $factura->cliente_pais ?> |
+
+
+
+
+
+
+
+
+ | Tipo y Nombre del trabajo |
+ Uds. |
+ Precio |
+ IVA |
+ Subtotal |
+
+
+
+
+ precio_unidad > 0): ?>
+
+ |
+ = nl2br($linea->descripcion); ?>
+ |
+
+ = ($linea->cantidad > 0) ? $linea->cantidad : '' ?>
+ |
+
+ = ($linea->cantidad > 0) ? $linea->precio_unidad : '' ?>
+ |
+
+ = ($linea->cantidad > 0) ? $linea->iva : '' ?>
+ |
+
+ = ($linea->cantidad > 0) ? $linea->base : '' ?>
+ |
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+ | BASE |
+ IVA |
+ TOTAL |
+
+
+
+
+
+ | = $tipo_iva->base ?> € |
+ = $tipo_iva->iva ?> % |
+ = $tipo_iva->total_iva ?> € |
+ = $tipo_iva->total ?> € |
+
+
+
+
+
+
+
+ | TOTAL |
+ = $factura->total ?> € |
+
+
+
+
+
+
+
+ | Vencimiento |
+ Fecha |
+ Forma de pago |
+ BIC / IBAN |
+
+
+
+
+ | = $factura->dias_vencimiento ?> días |
+ = $factura->vencimiento ?> |
+ = $factura->forma_pago ?> |
+
+ = ($factura->forma_pago == "Transferencias") ? 'ES33 2100 1134 14 1300319844' : $factura->cliente_ccc ?>
+ |
+
+
+
+
+
+
+
+
+
diff --git a/httpdocs/themes/vuexy/css/pdf.factura.css b/httpdocs/themes/vuexy/css/pdf.factura.css
new file mode 100644
index 00000000..c34cddfa
--- /dev/null
+++ b/httpdocs/themes/vuexy/css/pdf.factura.css
@@ -0,0 +1,313 @@
+/* Facturas Safekat */
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Open Sans', sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
+}
+
+table {
+ border-spacing: 0;
+ background-color: transparent;
+ border-collapse: collapse;
+}
+
+th {
+ text-align: left;
+}
+
+td {
+ padding: 0;
+}
+
+body table.logo {
+ padding: 0;
+ width: 100%;
+ color: black;
+}
+
+body table.logo td.logo img {
+ width: 100%;
+ vertical-align: middle;
+}
+/* Estilos intro-factura */
+body table.intro-factura {
+ width: 100%;
+ font-size: 12px;
+ margin-top: -22px;
+}
+
+body table.intro-factura th {
+ background: black;
+ color: white;
+ padding: 7px;
+}
+
+body table.intro-factura th.intro_num_factura {
+ width: 20%;
+ padding-left: 15px;
+}
+
+body table.intro-factura th.num_factura {
+ width: 47%;
+ font-weight: lighter;
+ text-align: left;
+}
+
+body table.intro-factura th.intro_fecha {
+ width: 17%;
+ text-align: right;
+}
+
+body table.intro-factura th.fecha {
+ width: 15%;
+ text-align: right;
+ font-weight: lighter;
+}
+
+body table.intro-factura td {
+ background: #e3e4e7;
+ padding-left: 15px;
+ color: black;
+ font-size: 12px;
+}
+
+body table.intro-factura td.intro_direccion {
+ padding-top: 10px;
+ padding-right: 8px;
+ font-weight: bold;
+}
+
+body table.intro-factura td.direccion {
+ padding-right: 8px;
+}
+
+/* Estilos cuerpo factura */
+div.cuerpo-factura {
+ margin-bottom: 25px;
+}
+
+table.factura-data-superior {
+ width: 100%;
+}
+
+table.factura-data-superior th {
+ padding: 5px !important;
+ background: #0C2C84;
+ color: white;
+ padding-left: 10px;
+ font-weight: lighter;
+ font-size: 12px;
+ border-right: 1px solid white;
+}
+
+table.factura-data-superior td {
+ border: 1px dotted #4e4e4e;
+ border-top: none;
+ padding: 5px !important;
+ text-align: right;
+ font-size: 11px;
+}
+
+table.factura-data-superior td.tipo_trabajo {
+ border-left: none;
+ text-align: left;
+}
+
+table.factura-data-superior td.subtotal {
+ border-right: none;
+}
+
+/* Estilos para el sello de Solunion */
+.sello-solunion {
+ float: left; /* Hace que el sello flote a la izquierda */
+ margin-left: 100px; /* Espacio entre el sello y la tabla */
+}
+
+.sello-solunion img {
+ display: block; /* Asegura que la imagen se comporte como un bloque dentro del div */
+ width: 80px; /* Ajusta el tamaño de la imagen según sea necesario */
+ height: auto;
+}
+
+/* Contenedor para manejar el flujo de contenido */
+.container {
+ overflow: hidden; /* Asegura que el contenedor se ajuste al contenido flotante */
+}
+
+/* Estilos para la tabla de precios inferior */
+table.factura-precio-inferior {
+ width: 60%; /* Ajusta el ancho de la tabla al 100% del contenedor */
+ text-align: right;
+ border-collapse: collapse; /* Asegura que los bordes se colapsen para evitar espacio extra */
+ margin-bottom: 0; /* Elimina el margen inferior para evitar espacio extra */
+}
+
+table.factura-precio-inferior th, table.factura-precio-inferior td {
+ padding: 5px;
+ border-bottom: 1px dotted #4e4e4e;
+}
+
+table.factura-precio-inferior th.intro_base,
+table.factura-precio-inferior th.intro_iva,
+table.factura-precio-inferior th.intro_total {
+ background: #0C2C84;
+ color: white;
+ font-size: 12px;
+}
+
+table.factura-precio-inferior td.base,
+table.factura-precio-inferior td.iva,
+table.factura-precio-inferior td.value_iva,
+table.factura-precio-inferior td.total {
+ font-size: 11px;
+}
+
+/* Estilos para la tabla de totales */
+table.totales {
+ width: 28%; /* Ajusta el ancho de la tabla según sea necesario */
+ background: #0C2C84;
+ color: white;
+ font-size: 12px;
+ border-collapse: collapse; /* Asegura que los bordes se colapsen para evitar espacio extra */
+ margin-top: 0; /* Elimina el margen superior para evitar espacio extra */
+ margin-bottom: 0; /* Elimina el margen inferior para evitar espacio extra */
+}
+
+table.totales td.intro_total_factura {
+ width: 20%;
+ text-align: right;
+ padding: 5px;
+}
+
+table.totales td.total_factura {
+ width: 15%;
+ text-align: right;
+ padding-right: 10px;
+}
+
+
+/* Estilos factura-data-inferior-iva */
+table.factura-data-inferior-iva {
+ width: 100%;
+ margin-top: 8px;
+}
+
+table.factura-data-inferior-iva th {
+ padding: 5px !important;
+ background: rgb(233, 240, 255);
+ font-weight: lighter;
+ font-size: 12px;
+ padding-left: 7px;
+ color: black;
+ border-right: 1px solid white;
+}
+
+table.factura-data-inferior-iva th.intro_vencimiento,
+table.factura-data-inferior-iva th.inferior_intro_fecha {
+ width: 15%;
+}
+
+table.factura-data-inferior-iva th.intro_forma_pago {
+ width: 20%;
+}
+
+table.factura-data-inferior-iva th.intro_bic {
+ width: 50%;
+}
+
+table.factura-data-inferior-iva td {
+ border-bottom: 1px dotted #4e4e4e;
+ border-top: none;
+ padding-left: 8px;
+ padding: 3px !important;
+ font-size: 11px;
+}
+
+table.factura-data-inferior-iva td.vencimiento,
+table.factura-data-inferior-iva td.inferior_fecha,
+table.factura-data-inferior-iva td.forma_pago {
+ border-right: 1px dotted black;
+}
+
+/* Estilos factura-precio-inferior */
+table.factura-data-inferior {
+ width: 100%;
+ background: #e3e4e7;
+ font-size: 12px;
+ margin-top: 5px;
+}
+
+table.factura-data-inferior th {
+ padding-top: 2px;
+ font-weight: lighter;
+}
+
+table.factura-data-inferior th.intro_vencimiento,
+table.factura-data-inferior th.intro_base,
+table.factura-data-inferior th.base {
+ padding-top: 8px;
+}
+
+table.factura-data-inferior th.intro_vencimiento,
+table.factura-data-inferior th.inferior_intro_fecha,
+table.factura-data-inferior th.intro_forma_pago,
+table.factura-data-inferior th.intro_bic {
+ font-weight: bold;
+ padding-left: 10px;
+}
+
+table.factura-data-inferior th.intro_base,
+table.factura-data-inferior th.intro_value_iva,
+table.factura-data-inferior th.intro_iva,
+table.factura-data-inferior th.intro_total {
+ color: #0C2C84;
+ text-align: right;
+ padding-right: 5px;
+}
+
+table.factura-data-inferior th.base,
+table.factura-data-inferior th.iva,
+table.factura-data-inferior th.value_iva,
+table.factura-data-inferior th.total {
+ border-left: 1px dashed grey;
+ text-align: right;
+ padding-right: 10px;
+ width: 15%;
+}
+
+table.factura-data-inferior th.intro_bic,
+table.factura-data-inferior th.intro_total,
+table.factura-data-inferior th.total {
+ padding-bottom: 8px;
+}
+
+/* Estilos para el pie de página */
+.footer {
+ width: 95%;
+ position: fixed; /* Fija el pie de página en la parte inferior */
+ bottom: 15px; /* Coloca el pie de página en la parte inferior de la página */
+}
+
+/* Estilos pie */
+div.pie {
+ font-family: sans-serif;
+ font-size: 7px;
+ margin: 5mm 0 5mm 0;
+}
+
+/* Estilos pie-pagina */
+table.pie-pagina {
+ font-family: sans-serif;
+ color: #0C2C84;
+ float: left;
+ vertical-align: bottom;
+ font-size: 10px;
+ font-weight: bold;
+}
\ No newline at end of file