729 lines
24 KiB
PHP
729 lines
24 KiB
PHP
<?php
|
|
|
|
// Validacion de token
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
|
|
if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { // Recorre todos los caracteres (siempre) y retorna true or false
|
|
$_SESSION['flash_error'] = 'Acción inválida.';
|
|
header('Location: index.php?opt=inicio_operador');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Requiere el modelo de presupuesto
|
|
|
|
require_once __DIR__ . '/../models/presupuestoModel.php';
|
|
$presupuestomodel = new presupuestoModel();
|
|
|
|
// Librería domPDF
|
|
|
|
require __DIR__ . '/../libs/dompdf/autoload.inc.php';
|
|
|
|
use Dompdf\Dompdf;
|
|
use Dompdf\Options;
|
|
|
|
// Validar sesion
|
|
|
|
if (!isset($_SESSION['user'])) {
|
|
header("Location: index.php?opt=login_operador");
|
|
exit;
|
|
}
|
|
|
|
$opt = $_GET['opt'] ?? null;
|
|
|
|
// Switch para manejo de opt
|
|
|
|
switch ($opt) {
|
|
|
|
// MOSTRAR VISTA DE CREACIÓN DE PRESUPUESTO
|
|
|
|
case 'crear_presupuesto':
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
|
|
// Obtenemos los productos de caja, pueder estar vacía o no
|
|
|
|
$productos = $presupuestomodel->listarProductos();
|
|
|
|
if (isset($_SESSION['presupuesto']['cliente'])) {
|
|
$cliente = $_SESSION['presupuesto']['cliente'];
|
|
} else {
|
|
$cliente = '';
|
|
}
|
|
|
|
// Llamamos a los métodos del modelo para obtener calculos preliminares
|
|
|
|
$subtotal = $presupuestomodel->calcularSubtotal() ?? 0;
|
|
$descuento = $presupuestomodel->calcularDescuentoTotal() ?? 0;
|
|
$total = $presupuestomodel->calcularPrecioTotal() ?? 0;
|
|
|
|
ob_start();
|
|
require __DIR__ . '/../views/presupuestos/crearPresupuestoView.php';
|
|
return ob_get_clean();
|
|
}
|
|
|
|
// AGREGAR PRODUCTO AL PRESUPUESTO (en casos de presupuesto, el manejo de productos es manejado por modelo de presupuesto)
|
|
|
|
case 'agregar_producto_presupuesto':
|
|
|
|
require_once __DIR__ . '/../models/productoModel.php';
|
|
$productomodel = new productoModel();
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
|
|
$productos = $productomodel->listarProductosVenta();
|
|
|
|
foreach ($productos as $i => $p) {
|
|
|
|
if (!isset($p['id'])) {
|
|
unset($productos[$i]);
|
|
continue;
|
|
}
|
|
|
|
if ($p['stock'] === null || $p['stock'] === 0) {
|
|
$productos[$i]['stock'] = '-';
|
|
}
|
|
|
|
$productos[$i]['descuento_total'] = number_format($p['descuento_total'], 2, '.', '') . ' %';
|
|
}
|
|
|
|
ob_start();
|
|
require __DIR__ . '/../views/presupuestos/agregarProductoView.php';
|
|
return ob_get_clean();
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
|
|
$ids = $_POST['ids'] ?? [];
|
|
$cantidades = $_POST['cantidades'] ?? [];
|
|
|
|
if (empty($ids)) {
|
|
$_SESSION['flash_error'] = 'No se seleccionó ningún producto.';
|
|
header('Location: index.php?opt=agregar_producto_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
$agregados = 0;
|
|
$errores = [];
|
|
|
|
// Evitar duplicados
|
|
|
|
$ids = array_unique($ids);
|
|
|
|
foreach ($ids as $idProducto) {
|
|
|
|
$idProducto = (int) $idProducto;
|
|
$cantidad = isset($cantidades[$idProducto]) ? (int) $cantidades[$idProducto] : 1;
|
|
|
|
if ($idProducto <= 0 || $cantidad <= 0) {
|
|
$errores[] = 'Datos inválidos.';
|
|
continue;
|
|
}
|
|
|
|
$producto = $productomodel->obtenerPorIdParaCaja($idProducto);
|
|
|
|
if (!$producto) {
|
|
$errores[] = 'Producto inexistente.';
|
|
continue;
|
|
}
|
|
|
|
if ($presupuestomodel->agregarProducto($producto, $cantidad)) {
|
|
$agregados++;
|
|
} else {
|
|
$errores[] = $presupuestomodel->getError();
|
|
}
|
|
}
|
|
|
|
if ($agregados === 1) {
|
|
$_SESSION['flash_success'] = "Se agregó un producto correctamente.";
|
|
} else if ($agregados > 1) {
|
|
$_SESSION['flash_success'] = "Se agregaron {$agregados} productos correctamente.";
|
|
}
|
|
|
|
if (!empty($errores)) {
|
|
$_SESSION['flash_error'] = implode('<br>', array_unique($errores));
|
|
header('Location: index.php?opt=agregar_producto_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
header('Location: index.php?opt=crear_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// ELIMINAR PRODUCTO DE CAJA
|
|
|
|
case 'eliminar_producto_presupuesto':
|
|
|
|
$idProducto = (int) ($_POST['id_producto'] ?? 0);
|
|
|
|
if ($idProducto <= 0) {
|
|
$_SESSION['flash_error'] = 'Datos inválidos.';
|
|
header('Location: index.php?opt=crear_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
if (!$presupuestomodel->eliminarProducto($idProducto)) {
|
|
$_SESSION['flash_error'] = $cajamodel->getError() ?? 'No se pudo eliminar el producto.';
|
|
} else {
|
|
$_SESSION['flash_success'] = 'Producto eliminado correctamente.';
|
|
}
|
|
|
|
header('Location: index.php?opt=crear_presupuesto');
|
|
exit;
|
|
|
|
// EDITAR CANTIDAD DEL PRODUCTO
|
|
|
|
case 'editar_cantidad_presupuesto':
|
|
|
|
$idProducto = (int) ($_POST['id_producto'] ?? 0);
|
|
$nuevaCantidad = (int) ($_POST['cantidad'] ?? 0);
|
|
|
|
if ($idProducto <= 0 || $nuevaCantidad <= 0) {
|
|
$_SESSION['flash_error'] = 'Datos inválidos.';
|
|
header('Location: index.php?opt=crear_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
if (!$presupuestomodel->editarCantidad($idProducto, $nuevaCantidad)) {
|
|
$_SESSION['flash_error'] = $presupuestomodel->getError() ?? 'No se pudo actualizar la cantidad.';
|
|
} else {
|
|
$_SESSION['flash_success'] = 'Cantidad editada correctamente.';
|
|
}
|
|
|
|
header('Location: index.php?opt=crear_presupuesto');
|
|
exit;
|
|
|
|
// SELECCIONAR CLIENTE PARA EL PRESUPUESTO
|
|
|
|
case 'seleccionar_cliente_presupuesto':
|
|
|
|
require_once __DIR__ . '/../models/clienteModel.php';
|
|
|
|
$clientemodel = new clienteModel();
|
|
|
|
// Se muestra la vista de selección de cliente
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
|
|
$clientes = $clientemodel->listarClientes();
|
|
|
|
ob_start();
|
|
require __DIR__ . '/../views/presupuestos/seleccionarClienteView.php';
|
|
return ob_get_clean();
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
|
|
$idCliente = (int) ($_POST['id_cliente'] ?? 0);
|
|
|
|
if ($idCliente <= 0) {
|
|
$_SESSION['flash_error'] = "No se seleccionó ningún cliente.";
|
|
header("Location: index.php?opt=seleccionar_cliente_presupuesto");
|
|
exit;
|
|
}
|
|
|
|
$cliente = $clientemodel->obtenerPorId($idCliente);
|
|
|
|
if (!$cliente) {
|
|
$_SESSION['flash_error'] = "Cliente inválido.";
|
|
header("Location: index.php?opt=seleccionar_cliente_presupuesto");
|
|
exit;
|
|
}
|
|
|
|
$_SESSION['presupuesto']['cliente'] = [
|
|
'id' => $cliente['id'],
|
|
'nombre' => $cliente['nombre'],
|
|
'apellido' => $cliente['apellido'],
|
|
'telefono' => $cliente['telefono'],
|
|
'email' => $cliente['email'],
|
|
'cuit' => $cliente['cuit'],
|
|
'cond_iva' => $cliente['cond_iva']
|
|
];
|
|
|
|
$_SESSION['presupuesto_extra']['cond_iva'] = $cliente['cond_iva'];
|
|
$_SESSION['presupuesto_extra']['cuit'] = $cliente['cuit'];
|
|
|
|
$_SESSION['flash_success'] = "Cliente agregado correctamente.";
|
|
header("Location: index.php?opt=crear_presupuesto");
|
|
exit;
|
|
}
|
|
|
|
// ELIMINAR CLIENTE YA SELECCIONADO
|
|
|
|
case 'eliminar_cliente_presupuesto':
|
|
|
|
if (isset($_SESSION['presupuesto']['cliente'])) {
|
|
unset($_SESSION['presupuesto']['cliente']);
|
|
|
|
// También se eliminan datos del presupuesto guardados desde vista resumen
|
|
|
|
if (isset($_SESSION['presupuesto_extra'])) {
|
|
unset($_SESSION['presupuesto_extra']);
|
|
unset($_SESSION['presupuesto_final']);
|
|
}
|
|
|
|
$_SESSION['flash_success'] = "Cliente eliminado correctamente.";
|
|
} else {
|
|
$_SESSION['flash_error'] = "No había cliente seleccionado.";
|
|
}
|
|
|
|
header("Location: index.php?opt=crear_presupuesto");
|
|
exit;
|
|
|
|
// VACIAR CAJA DE PRODUCTOS
|
|
|
|
case 'vaciar_caja_presupuesto':
|
|
|
|
if ($presupuestomodel->vaciarCajaPresupuesto()) {
|
|
$_SESSION['flash_success'] = 'Carrito vaciado.';
|
|
} else {
|
|
$_SESSION['flash_error'] = 'No se pudo vaciar el carrito.';
|
|
}
|
|
|
|
header('Location: index.php?opt=crear_presupuesto');
|
|
exit;
|
|
|
|
// GENERAR VISTA RESUMEN DE PRESUPUESTO
|
|
|
|
case 'resumen_presupuesto':
|
|
|
|
$cliente = ($_SESSION['presupuesto']['cliente'] ?? null);
|
|
|
|
$_SESSION['presupuesto_extra']['cond_iva'] = $_SESSION['presupuesto_extra']['cond_iva'] ?? $cliente['cond_iva'] ?? 'consumidor_final';
|
|
$_SESSION['presupuesto_extra']['cuit'] = $_SESSION['presupuesto_extra']['cuit'] ?? $cliente['cuit'] ?? '00000000000';
|
|
|
|
$productos = $presupuestomodel->listarProductos();
|
|
$descuento = $presupuestomodel->calcularDescuentoTotal();
|
|
|
|
if (!$cliente || empty($productos)) {
|
|
$_SESSION['flash_error'] = "Debe seleccionar el cliente y al menos un producto.";
|
|
header("Location: index.php?opt=crear_presupuesto");
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
|
|
// 1. Subtotal SIEMPRE se recalcula (pueden haber cambiado productos/cantidades)
|
|
|
|
$subtotal = $presupuestomodel->calcularSubtotal() ?? 0;
|
|
|
|
// 2. Datos extra guardados en sesión (si existen)
|
|
|
|
$descuentoIngresado = isset($_SESSION['presupuesto_extra']['descuento']) ? (float) $_SESSION['presupuesto_extra']['descuento'] : 0;
|
|
|
|
$recargoIngresado = isset($_SESSION['presupuesto_extra']['recargo']) ? (float) $_SESSION['presupuesto_extra']['recargo'] : 0;
|
|
|
|
// 3. Recalculo siempre con subtotal actual
|
|
|
|
$datosProvisorios = $presupuestomodel->actualizarDatosProvisorio($descuentoIngresado, $recargoIngresado, $subtotal, $descuento);
|
|
|
|
$descuento = $datosProvisorios['descuento'] ?? 0;
|
|
$recargo = $datosProvisorios['recargo'] ?? 0;
|
|
$total = $datosProvisorios['total'] ?? 0;
|
|
|
|
// Guardo en SESSION
|
|
|
|
$_SESSION['presupuesto_final'] = [
|
|
'descuento' => $descuento,
|
|
'recargo' => $recargo,
|
|
'total' => $total
|
|
];
|
|
|
|
ob_start();
|
|
require __DIR__ . '/../views/presupuestos/resumenPresupuestoView.php';
|
|
return ob_get_clean();
|
|
}
|
|
|
|
// GUARDAR DATOS DEL PRESUPUESTO (permite volver hacia atrás en el proceso y no perder datos)
|
|
|
|
case 'guardar_datos_presupuesto':
|
|
|
|
// Validaciones de reglas de negocio
|
|
|
|
// Condición IVA
|
|
|
|
$condIvaPermitidas = [
|
|
'consumidor_final',
|
|
'responsable_inscripto',
|
|
'monotributo'
|
|
];
|
|
|
|
$condIva = $_POST['cond_iva'] ?? 'consumidor_final';
|
|
|
|
if (!in_array($condIva, $condIvaPermitidas, true)) {
|
|
|
|
$_SESSION['flash_error'] = 'Condición de IVA inválida.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// CUIT
|
|
|
|
$cuit = ($_POST['cuit_1'] ?? '') . ($_POST['cuit_2'] ?? '') . ($_POST['cuit_3'] ?? '');
|
|
|
|
$cuit = trim($cuit);
|
|
|
|
if ($cuit === '') {
|
|
|
|
$_SESSION['flash_error'] = 'Debe ingresar un CUIT.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
if (!preg_match('/^\d{11}$/', $cuit)) {
|
|
|
|
$_SESSION['flash_error'] = 'El CUIT debe contener 11 dígitos.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// Forma de pago + tipo de pago
|
|
|
|
$reglasPago = [
|
|
'efectivo' => ['pago_unico'],
|
|
'transferencia' => ['pago_unico'],
|
|
'echeq' => ['pago_unico'],
|
|
'debito' => ['pago_unico'],
|
|
'credito' => ['pago_unico', '3_cuotas', '6_cuotas', '12_cuotas'],
|
|
];
|
|
|
|
$formaPago = $_POST['forma_pago'] ?? 'efectivo';
|
|
$tipoPago = $_POST['tipo_pago'] ?? 'pago_unico';
|
|
|
|
if (!isset($reglasPago[$formaPago]) || !in_array($tipoPago, $reglasPago[$formaPago], true)) {
|
|
$_SESSION['flash_error'] = 'Combinación de forma y tipo de pago inválida.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// Validación de descuento y recargo
|
|
|
|
$descuentoPresupuesto = isset($_POST['descuento']) ? (float) $_POST['descuento'] : 0;
|
|
$recargoPresupuesto = isset($_POST['recargo']) ? (float) $_POST['recargo'] : 0;
|
|
|
|
if ($descuentoPresupuesto < 0 || $descuentoPresupuesto > 100) {
|
|
$_SESSION['flash_error'] = 'El descuento debe estar entre 0 y 100%.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
if ($recargoPresupuesto < 0 || $recargoPresupuesto > 100) {
|
|
$_SESSION['flash_error'] = 'El recargo debe estar entre 0 y 100%.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// Guardado de datos
|
|
|
|
// Datos extra del presupuesto
|
|
|
|
$datosExtraPresupuesto = [
|
|
'cond_iva' => $condIva,
|
|
'cuit' => $cuit,
|
|
'forma_pago' => $formaPago,
|
|
'tipo_pago' => $tipoPago,
|
|
'descuento' => $descuentoPresupuesto,
|
|
'recargo' => $recargoPresupuesto
|
|
];
|
|
|
|
// También los persisto en sesión para mantener estado
|
|
|
|
$_SESSION['presupuesto_extra'] = $datosExtraPresupuesto;
|
|
|
|
// Datos para la vista
|
|
|
|
require_once __DIR__ . '/../models/clienteModel.php';
|
|
$clientemodel = new clienteModel();
|
|
|
|
$idCliente = ($_SESSION['presupuesto']['cliente']['id'] ?? null);
|
|
$productos = $presupuestomodel->listarProductos();
|
|
|
|
if ($idCliente === null) {
|
|
$_SESSION['flash_error'] = 'No seleccionó un cliente.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
$vendedor = $_SESSION['user'] ?? null;
|
|
$cliente = $clientemodel->obtenerPorId($idCliente);
|
|
|
|
if (!$cliente) {
|
|
$_SESSION['flash_error'] = 'No se pudo identificar el cliente.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
if (!$vendedor) {
|
|
$_SESSION['flash_error'] = 'No se pudo identificar el usuario.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
/* Subtotal que no contiene descuentos.
|
|
(Al ingresar descuento o recargo, lo guardo en un array separado, para no sobreescribir datos) */
|
|
|
|
$subtotal = $presupuestomodel->calcularSubtotal() ?? 0;
|
|
$descuento = $presupuestomodel->calcularDescuentoTotal() ?? 0;
|
|
|
|
// Validación del subtotal
|
|
|
|
if ($subtotal <= 0) {
|
|
$_SESSION['flash_error'] = 'El presupuesto no contiene productos válidos.';
|
|
header('Location: index.php?opt=crear_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// Llamamos a la función que devuelve los datos actualizados en un array nuevo
|
|
|
|
$datosProvisorios = $presupuestomodel->actualizarDatosProvisorio($descuentoPresupuesto, $recargoPresupuesto, $subtotal, $descuento);
|
|
|
|
$recargo = $datosProvisorios['recargo'] ?? 0;
|
|
$descuento = $datosProvisorios['descuento'] ?? 0;
|
|
$total = $datosProvisorios['total'] ?? 0;
|
|
|
|
$_SESSION['presupuesto_final'] = [
|
|
'recargo' => $recargo,
|
|
'descuento' => $descuento,
|
|
'total' => $total
|
|
];
|
|
|
|
$_SESSION['flash_success'] = "Datos guardados de manera provisoria.";
|
|
header("Location: index.php?opt=resumen_presupuesto");
|
|
exit;
|
|
|
|
// GENERACION DE PRESUPUESTO PDF MEDIANTE USO DE LIBRERIA DOMPDF
|
|
|
|
case 'generar_presupuesto_pdf':
|
|
|
|
// Requiero datos de empresa y configuración
|
|
|
|
require __DIR__ . '/../models/configuracionModel.php';
|
|
$configuracionmodel = new configuracionModel();
|
|
|
|
$datosEmpresa = $configuracionmodel->obtenerConfiguracion();
|
|
|
|
$mapCondIVA = [
|
|
'consumidor_final' => 'Consumidor Final',
|
|
'responsable_inscripto' => 'Responsable Inscripto',
|
|
'monotributo' => 'Monotributo',
|
|
];
|
|
|
|
$datosEmpresa['cond_iva'] = $mapCondIVA[$datosEmpresa['cond_iva']];
|
|
|
|
// Requiero modelos de presupuesto y cliente
|
|
|
|
require_once __DIR__ . '/../models/presupuestoModel.php';
|
|
$presupuestomodel = new presupuestoModel();
|
|
|
|
require_once __DIR__ . '/../models/clienteModel.php';
|
|
$clientemodel = new clienteModel();
|
|
|
|
$productos = $presupuestomodel->listarProductos();
|
|
$idCliente = $_SESSION['presupuesto']['cliente']['id'] ?? null;
|
|
|
|
if ($idCliente === null) {
|
|
$_SESSION['flash_error'] = 'No seleccionó un cliente.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
$vendedor = $_SESSION['user'] ?? null;
|
|
$cliente = $clientemodel->obtenerPorId($idCliente);
|
|
|
|
// DATOS FORM (requiero todo de nuevo desde el formulario mediante POST, no utilizo los datos ya almacenados en $_SESSION (son unicamente para mantener estado))
|
|
|
|
$condIVA = $_POST['cond_iva'] ?? '';
|
|
$cuit = ($_POST['cuit_1'] ?? '') . ($_POST['cuit_2'] ?? '') . ($_POST['cuit_3'] ?? '');
|
|
$formaPago = $_POST['forma_pago'] ?? '';
|
|
$tipoPago = $_POST['tipo_pago'] ?? '';
|
|
|
|
$descuentoPresupuesto = $_POST['descuento'] ?? 0;
|
|
$recargoPresupuesto = $_POST['recargo'] ?? 0;
|
|
|
|
// VALIDACIONES BASE
|
|
|
|
if (!$cliente || empty($productos)) {
|
|
$_SESSION['flash_error'] = 'Datos incompletos para generar el presupuesto.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
if (!$vendedor) {
|
|
$_SESSION['flash_error'] = 'No se pudo identificar el usuario.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// VALIDACIÓN CONDICIÓN IVA
|
|
|
|
$condIvaPermitidas = [
|
|
'consumidor_final',
|
|
'responsable_inscripto',
|
|
'monotributo'
|
|
];
|
|
|
|
if (!in_array($condIVA, $condIvaPermitidas, true)) {
|
|
$_SESSION['flash_error'] = 'Condición de IVA inválida.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// VALIDACIÓN CUIT
|
|
|
|
$cuit = trim($cuit);
|
|
|
|
if (!preg_match('/^\d{10,11}$/', $cuit)) {
|
|
$_SESSION['flash_error'] = 'CUIT inválido. Debe contener solo números.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// VALIDACIÓN FORMA + TIPO DE PAGO
|
|
|
|
$reglasPago = [
|
|
'efectivo' => ['pago_unico'],
|
|
'transferencia' => ['pago_unico'],
|
|
'echeq' => ['pago_unico'],
|
|
'debito' => ['pago_unico'],
|
|
'credito' => ['pago_unico', '3_cuotas', '6_cuotas', '12_cuotas'],
|
|
];
|
|
|
|
if (!isset($reglasPago[$formaPago]) || !in_array($tipoPago, $reglasPago[$formaPago], true)) {
|
|
$_SESSION['flash_error'] = 'Combinación de forma y tipo de pago inválida.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// VALIDACIÓN DESCUENTO / RECARGO
|
|
|
|
if ($descuentoPresupuesto < 0 || $descuentoPresupuesto > 100) {
|
|
$_SESSION['flash_error'] = 'El descuento debe estar entre 0 y 100%.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
if ($recargoPresupuesto < 0 || $recargoPresupuesto > 100) {
|
|
$_SESSION['flash_error'] = 'El recargo debe estar entre 0 y 100%.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// RECÁLCULO DE TOTALES (SIEMPRE)
|
|
|
|
$subtotal = $presupuestomodel->calcularSubtotal() ?? 0;
|
|
|
|
if ($subtotal <= 0) {
|
|
$_SESSION['flash_error'] = 'El presupuesto no contiene productos válidos.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
$descuentoProductos = $presupuestomodel->calcularDescuentoTotal() ?? 0;
|
|
|
|
$datosProvisorios = $presupuestomodel->actualizarDatosProvisorio($descuentoPresupuesto, $recargoPresupuesto, $subtotal, $descuentoProductos);
|
|
|
|
$recargo = $datosProvisorios['recargo'] ?? 0;
|
|
$descuento = $datosProvisorios['descuento'] ?? 0;
|
|
$total = $datosProvisorios['total'] ?? 0;
|
|
|
|
if ($total <= 0) {
|
|
$_SESSION['flash_error'] = 'Total inválido.';
|
|
header('Location: index.php?opt=resumen_presupuesto');
|
|
exit;
|
|
}
|
|
|
|
// MAPEOS PARA PDF
|
|
|
|
$mapCondIVA = [
|
|
'consumidor_final' => 'Consumidor Final',
|
|
'responsable_inscripto' => 'Responsable Inscripto',
|
|
'monotributo' => 'Monotributo',
|
|
];
|
|
|
|
$mapFormaPago = [
|
|
'efectivo'=> 'Efectivo',
|
|
'transferencia' => 'Transferencia',
|
|
'debito' => 'Débito',
|
|
'credito' => 'Crédito',
|
|
'echeq' => 'Echeq',
|
|
];
|
|
|
|
$mapTipoPago = [
|
|
'pago_unico' => 'Pago Único',
|
|
'3_cuotas' => '3 Cuotas',
|
|
'6_cuotas' => '6 Cuotas',
|
|
'12_cuotas' => '12 Cuotas',
|
|
];
|
|
|
|
$condIVALabel = $mapCondIVA[$condIVA];
|
|
$formaPagoLabel = $mapFormaPago[$formaPago];
|
|
$tipoPagoLabel = $mapTipoPago[$tipoPago];
|
|
|
|
// CÁLCULO DE CUOTAS
|
|
|
|
if ($tipoPago !== 'pago_unico') {
|
|
$cuota = (int) explode('_', $tipoPago)[0];
|
|
$valorCuota = $total / $cuota;
|
|
}
|
|
|
|
// NÚMERO DE PRESUPUESTO (RANDOM) (decidí dejarlo con código aleatorio, se podría modificar perfectamente)
|
|
|
|
$parte2 = str_pad((string) rand(0, 99999999), 8, '0', STR_PAD_LEFT);
|
|
$numeroPresupuesto = '0001' . '-' . $parte2;
|
|
|
|
// RENDER PDF
|
|
|
|
ob_start();
|
|
require __DIR__ . '/../pdf/presupuestos/presupuestoPDF.php';
|
|
$html = ob_get_clean();
|
|
|
|
$cssPath = '/var/www/html/css/stylesPDF.css';
|
|
$css = file_get_contents($cssPath);
|
|
|
|
// Configuración de opciones
|
|
|
|
$options = new Options();
|
|
$options->set('isRemoteEnabled', true); // Permite cargar recursos externos (CSS, imágenes, etc.)
|
|
$options->set('chroot', '/var/www/html'); // Define directorios base para recursos locales
|
|
$options->set('defaultFont', 'DejaVu Sans');
|
|
|
|
// Creación de instancia Dompdf con las opciones seteadas
|
|
|
|
$dompdf = new Dompdf($options);
|
|
|
|
// Cargar el HTML que se va a convertir en PDF
|
|
|
|
$dompdf->loadHtml("
|
|
<style>$css</style>
|
|
$html
|
|
");
|
|
|
|
$dompdf->setPaper('A4', 'portrait'); // Define el tamanio de hoja y la orientación
|
|
$dompdf->render(); // Renderiza el PDF (procesa el HTML)
|
|
|
|
// Enviar el PDF al browser
|
|
|
|
$dompdf->stream(
|
|
'Presupuesto N° ' . $numeroPresupuesto . '.pdf',
|
|
['Attachment' => true] // false = se muestra en el navegador | true = descarga directa
|
|
);
|
|
|
|
// Eliminamos datos ingresados y vaciamos caja
|
|
|
|
$presupuestomodel->vaciarCajaPresupuesto();
|
|
unset(($_SESSION)['presupuesto']['cliente']);
|
|
unset($_SESSION['presupuesto_final']);
|
|
unset($_SESSION['presupuesto_extra']);
|
|
unset($_SESSION['prov_presupuesto']);
|
|
|
|
exit;
|
|
|
|
// DEFAULT (404)
|
|
|
|
default:
|
|
|
|
ob_start();
|
|
header("Location: index.php?opt=404View.php");
|
|
return ob_get_clean();
|
|
} |