Carpeta controllers
This commit is contained in:
@@ -0,0 +1,944 @@
|
||||
<?php
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Librería domPDF
|
||||
|
||||
require __DIR__ . '/../libs/dompdf/autoload.inc.php';
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Options;
|
||||
|
||||
// Validar sesión
|
||||
|
||||
if (!isset($_SESSION['user'])) {
|
||||
header("Location: index.php?opt=login_operador");
|
||||
exit;
|
||||
}
|
||||
|
||||
$opt = $_GET['opt'] ?? null;
|
||||
|
||||
// Manejo de $opt
|
||||
|
||||
switch ($opt) {
|
||||
|
||||
// CREAR VENTA
|
||||
|
||||
case 'crear_venta':
|
||||
|
||||
// Se muestra la vista de creación de ventas
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
|
||||
// Requiero el modelo de caja (puede estar vacía)
|
||||
|
||||
require_once __DIR__ . '/../models/cajaModel.php';
|
||||
$cajamodel = new cajaModel();
|
||||
|
||||
$productos = $cajamodel->listarProductos();
|
||||
|
||||
if (isset($_SESSION['venta']['cliente'])) {
|
||||
$cliente = $_SESSION['venta']['cliente'];
|
||||
} else {
|
||||
$cliente = '';
|
||||
}
|
||||
|
||||
// Obtengo cálculos preliminares
|
||||
|
||||
$subtotal = $cajamodel->calcularSubtotal() ?? 0;
|
||||
$descuento = $cajamodel->calcularDescuentoTotal() ?? 0;
|
||||
$total = $cajamodel->calcularPrecioTotal() ?? 0;
|
||||
|
||||
ob_start();
|
||||
require __DIR__ . '/../views/ventas/crearVentaView.php';
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
// AGREGAR PRODUCTO A LA VENTA (el post es atendido por CAJA)
|
||||
|
||||
case 'agregar_producto':
|
||||
|
||||
// Requiero el productoModel
|
||||
|
||||
require_once __DIR__ . '/../models/productoModel.php';
|
||||
$productomodel = new productoModel();
|
||||
|
||||
$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/ventas/agregarProductoView.php';
|
||||
return ob_get_clean();
|
||||
|
||||
// SELECCIONAR CLIENTE PARA LA VENTA
|
||||
|
||||
case 'seleccionar_cliente':
|
||||
|
||||
// Requiero el modelo de cliente
|
||||
|
||||
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/ventas/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");
|
||||
exit;
|
||||
}
|
||||
|
||||
$cliente = $clientemodel->obtenerPorId($idCliente);
|
||||
|
||||
if (!$cliente) {
|
||||
$_SESSION['flash_error'] = "Cliente inválido.";
|
||||
header("Location: index.php?opt=seleccionar_cliente");
|
||||
exit;
|
||||
}
|
||||
|
||||
$_SESSION['venta']['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['venta_extra']['cond_iva'] = $cliente['cond_iva'];
|
||||
$_SESSION['venta_extra']['cuit'] = $cliente['cuit'];
|
||||
|
||||
$_SESSION['flash_success'] = "Cliente agregado correctamente.";
|
||||
header("Location: index.php?opt=crear_venta");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ELIMINAR CLIENTE YA SELECCIONADO
|
||||
|
||||
case 'eliminar_cliente':
|
||||
|
||||
if (isset($_SESSION['venta']['cliente'])) {
|
||||
unset($_SESSION['venta']['cliente']);
|
||||
|
||||
// También se eliminan datos de la venta guardados desde vista resumen
|
||||
|
||||
if (isset($_SESSION['venta_extra'])) {
|
||||
unset($_SESSION['venta_extra']);
|
||||
unset($_SESSION['venta_final']);
|
||||
}
|
||||
|
||||
$_SESSION['flash_success'] = "Cliente eliminado correctamente.";
|
||||
} else {
|
||||
$_SESSION['flash_error'] = "No había cliente seleccionado.";
|
||||
}
|
||||
|
||||
header("Location: index.php?opt=crear_venta");
|
||||
exit;
|
||||
|
||||
// GENERAR VISTA RESUMEN DE VENTA
|
||||
|
||||
case 'resumen_venta':
|
||||
|
||||
$cliente = ($_SESSION['venta']['cliente'] ?? null);
|
||||
|
||||
$_SESSION['venta_extra']['cond_iva'] = $_SESSION['venta_extra']['cond_iva'] ?? $cliente['cond_iva'] ?? 'consumidor_final';
|
||||
$_SESSION['venta_extra']['cuit'] = $_SESSION['venta_extra']['cuit'] ?? $cliente['cuit'] ?? '00000000000';
|
||||
|
||||
// Requiero el modelo de caja
|
||||
|
||||
require_once __DIR__ . '/../models/cajaModel.php';
|
||||
$cajamodel = new cajaModel();
|
||||
|
||||
$productos = $cajamodel->listarProductos();
|
||||
$descuento = $cajamodel->calcularDescuentoTotal();
|
||||
|
||||
if (!$cliente || empty($productos)) {
|
||||
$_SESSION['flash_error'] = "Debe seleccionar el cliente y al menos un producto.";
|
||||
header("Location: index.php?opt=crear_venta");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
|
||||
require_once __DIR__ . '/../models/ventaModel.php';
|
||||
|
||||
$ventamodel = new ventaModel();
|
||||
|
||||
// 1. Subtotal SIEMPRE se recalcula (pueden haber cambiado productos/cantidades)
|
||||
|
||||
$subtotal = $cajamodel->calcularSubtotal() ?? 0;
|
||||
|
||||
// 2. Datos extra guardados en sesión (si existen)
|
||||
|
||||
$descuentoIngresado = isset($_SESSION['venta_extra']['descuento']) ? (float) $_SESSION['venta_extra']['descuento'] : 0;
|
||||
|
||||
$recargoIngresado = isset($_SESSION['venta_extra']['recargo']) ? (float) $_SESSION['venta_extra']['recargo'] : 0;
|
||||
|
||||
// 3. Recalculo siempre con subtotal actual
|
||||
|
||||
$datosProvisorios = $ventamodel->actualizarDatosProvisorio($descuentoIngresado, $recargoIngresado, $subtotal, $descuento);
|
||||
|
||||
$descuento = $datosProvisorios['descuento'] ?? 0;
|
||||
$recargo = $datosProvisorios['recargo'] ?? 0;
|
||||
$total = $datosProvisorios['total'] ?? 0;
|
||||
|
||||
// Guardo en SESSION
|
||||
|
||||
$_SESSION['venta_final'] = [
|
||||
'descuento' => $descuento,
|
||||
'recargo' => $recargo,
|
||||
'total' => $total
|
||||
];
|
||||
|
||||
ob_start();
|
||||
require __DIR__ . '/../views/ventas/resumenVentaView.php';
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
// GUARDAR DATOS DE VENTA (permite volver hacia atrás en el proceso y no perder datos)
|
||||
|
||||
case 'guardar_datos_venta':
|
||||
|
||||
// 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_venta');
|
||||
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_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!preg_match('/^\d{11}$/', $cuit)) {
|
||||
|
||||
$_SESSION['flash_error'] = 'El CUIT debe contener 11 dígitos.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
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_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validación de descuento y recargo
|
||||
|
||||
$descuentoVenta = isset($_POST['descuento']) ? (float) $_POST['descuento'] : 0;
|
||||
$recargoVenta = isset($_POST['recargo']) ? (float) $_POST['recargo'] : 0;
|
||||
|
||||
if ($descuentoVenta < 0 || $recargoVenta > 100) {
|
||||
$_SESSION['flash_error'] = 'El descuento debe estar entre 0 y 100%.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($descuentoVenta < 0 || $recargoVenta > 100) {
|
||||
$_SESSION['flash_error'] = 'El recargo debe estar entre 0 y 100%.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Guardado de datos
|
||||
|
||||
// Guardo datos extra de la venta para ser reutilizados en la vista
|
||||
|
||||
$datosExtraVenta = [
|
||||
'cond_iva' => $condIva,
|
||||
'cuit' => $cuit,
|
||||
'forma_pago' => $formaPago,
|
||||
'tipo_pago' => $tipoPago,
|
||||
'descuento' => $descuentoVenta,
|
||||
'recargo' => $recargoVenta
|
||||
];
|
||||
|
||||
// También los persisto en sesión para mantener estado
|
||||
|
||||
$_SESSION['venta_extra'] = $datosExtraVenta;
|
||||
|
||||
// Datos para la vista
|
||||
|
||||
require_once __DIR__ . '/../models/cajaModel.php';
|
||||
$cajamodel = new cajaModel();
|
||||
|
||||
$cliente = ($_SESSION['venta']['cliente'] ?? null);
|
||||
$productos = $cajamodel->listarProductos();
|
||||
|
||||
$vendedor = $_SESSION['user'] ?? null;
|
||||
|
||||
// VALIDACIONES BASE
|
||||
|
||||
if (!$cliente || empty($productos)) {
|
||||
$_SESSION['flash_error'] = 'Datos incompletos para generar la venta.';
|
||||
header('Location: index.php?opt=crear_pedido');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$vendedor) {
|
||||
$_SESSION['flash_error'] = 'No se pudo identificar el usuario.';
|
||||
header('Location: index.php?opt=crear_pedido');
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Subtotal que no contiene descuentos.
|
||||
(Al ingresar descuento o recargo, lo guardo en un array separado, para no sobreescribir datos) */
|
||||
|
||||
$subtotal = $cajamodel->calcularSubtotal() ?? 0;
|
||||
$descuento = $cajamodel->calcularDescuentoTotal() ?? 0;
|
||||
|
||||
// Validación del subtotal
|
||||
|
||||
if ($subtotal <= 0) {
|
||||
$_SESSION['flash_error'] = 'La venta no contiene productos válidos.';
|
||||
header('Location: index.php?opt=crear_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Llamamos a la función que devuelve los datos actualizados en un array nuevo
|
||||
|
||||
require_once __DIR__ . '/../models/ventaModel.php';
|
||||
|
||||
$ventamodel = new ventaModel();
|
||||
|
||||
$datosProvisorios = $ventamodel->actualizarDatosProvisorio($descuentoVenta, $recargoVenta, $subtotal, $descuento);
|
||||
|
||||
$recargo = $datosProvisorios['recargo'] ?? 0;
|
||||
$descuento = $datosProvisorios['descuento'] ?? 0;
|
||||
$total = $datosProvisorios['total'] ?? 0;
|
||||
|
||||
$_SESSION['venta_final'] = [
|
||||
'recargo' => $recargo,
|
||||
'descuento' => $descuento,
|
||||
'total' => $total
|
||||
];
|
||||
|
||||
$_SESSION['flash_success'] = "Datos guardados de manera provisoria.";
|
||||
header("Location: index.php?opt=resumen_venta");
|
||||
exit;
|
||||
|
||||
// GENERACION DE VENTA PDF MEDIANTE USO DE LIBRERIA DOMPDF
|
||||
|
||||
case 'generar_venta_pdf':
|
||||
|
||||
// OBTENEMOS LA VISTA
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
|
||||
$numeroVenta = $_SESSION['ultima_venta_id'];
|
||||
|
||||
ob_start();
|
||||
require __DIR__ . '/../views/ventas/descargarComprobante.php';
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
// GENERACIÓN DEL PDF
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
// 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']];
|
||||
|
||||
// Obtenemos array con datos necesarios, que fueron guardados durante la confirmación de venta en $_SESSION
|
||||
|
||||
$datosVenta = $_SESSION['venta_pdf'] ?? null;
|
||||
|
||||
if (!$datosVenta) {
|
||||
$_SESSION['flash_error'] = 'No existen datos para generar el comprobante.';
|
||||
header('Location: index.php?opt=crear_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Asignamos datos a variables y validamos
|
||||
|
||||
$cliente = $datosVenta['cliente'];
|
||||
$vendedor = $datosVenta['vendedor'];
|
||||
$productos = $datosVenta['productos'];
|
||||
|
||||
// VALIDACIONES BASE
|
||||
|
||||
if (!$cliente || empty($productos)) {
|
||||
$_SESSION['flash_error'] = 'Datos incompletos para generar la venta.';
|
||||
header('Location: index.php?opt=crear_pedido');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$vendedor) {
|
||||
$_SESSION['flash_error'] = 'No se pudo identificar el usuario.';
|
||||
header('Location: index.php?opt=crear_pedido');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Asignamos datos a variables y validamos
|
||||
|
||||
$condIVA = $datosVenta['cond_iva'];
|
||||
$cuit = $datosVenta['cuit'];
|
||||
|
||||
$formaPago = $datosVenta['forma_pago'];
|
||||
$tipoPago = $datosVenta['tipo_pago'];
|
||||
|
||||
$descuentoVenta = $datosVenta['descuentoVenta'];
|
||||
$recargoVenta = $datosVenta['recargoVenta'];
|
||||
|
||||
// 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_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validación de CUIT
|
||||
|
||||
$cuit = trim($cuit);
|
||||
|
||||
if (!preg_match('/^\d{10,11}$/', $cuit)) {
|
||||
$_SESSION['flash_error'] = 'CUIT inválido.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
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_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// VALIDACIÓN DESCUENTO / RECARGO
|
||||
|
||||
if ($descuentoVenta < 0 || $descuentoVenta > 100) {
|
||||
$_SESSION['flash_error'] = 'El descuento debe estar entre 0 y 100%.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($recargoVenta < 0 || $recargoVenta > 100) {
|
||||
$_SESSION['flash_error'] = 'El recargo debe estar entre 0 y 100%.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
$subtotal = $datosVenta['subtotal'];
|
||||
|
||||
if ($subtotal <= 0) {
|
||||
$_SESSION['flash_error'] = 'La venta no contiene productos válidos.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Asignamos datos a variables y validamos
|
||||
|
||||
$descuento = $datosVenta['descuento'];
|
||||
$recargo = $datosVenta['recargo'];
|
||||
$total = $datosVenta['total'];
|
||||
|
||||
if ($total <= 0) {
|
||||
$_SESSION['flash_error'] = 'Total inválido.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
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;
|
||||
}
|
||||
|
||||
// Obtenemos el número de venta que se obtuvo desde la base de datos al momento de guardar la venta
|
||||
|
||||
$numero = $_SESSION['ultima_venta_id'] ?? null;
|
||||
|
||||
if (!$numero) {
|
||||
$_SESSION['flash_error'] = 'No se encontró el número de venta.';
|
||||
header('Location: index.php?opt=crear_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Variable para mostrar el código en la vista
|
||||
|
||||
$numeroVenta = '0001-' . str_pad($numero, 8, '0', STR_PAD_LEFT);
|
||||
|
||||
// RENDER PDF
|
||||
|
||||
ob_start();
|
||||
require __DIR__ . '/../pdf/ventas/ventaPDF.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(
|
||||
'Venta N° ' . $numeroVenta . '.pdf',
|
||||
['Attachment' => true] // false = se muestra en el navegador | true = descarga directa
|
||||
);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// CONTINUAR SIN DESCARGAR EL COMPROBANTE PDF
|
||||
|
||||
case 'continuar_sin_comprobante':
|
||||
|
||||
// Liberamos $_SESSION
|
||||
|
||||
unset($_SESSION['venta_pdf']);
|
||||
unset($_SESSION['ultima_venta_id']);
|
||||
|
||||
$_SESSION['flash_success'] = 'Venta finalizada correctamente.';
|
||||
|
||||
header('Location: index.php?opt=crear_venta');
|
||||
exit;
|
||||
|
||||
// CONFIRMAR VENTA
|
||||
|
||||
case 'confirmar_venta':
|
||||
|
||||
// Validaciones de regla 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_venta');
|
||||
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_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!preg_match('/^\d{11}$/', $cuit)) {
|
||||
|
||||
$_SESSION['flash_error'] = 'El CUIT debe contener 11 dígitos.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
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_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validación de descuento y recargo
|
||||
|
||||
$descuentoVenta = isset($_POST['descuento']) ? (float) $_POST['descuento'] : 0;
|
||||
$recargoVenta = isset($_POST['recargo']) ? (float) $_POST['recargo'] : 0;
|
||||
|
||||
if ($descuentoVenta < 0 || $descuentoVenta > 100) {
|
||||
$_SESSION['flash_error'] = 'El descuento debe estar entre 0 y 100%.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($recargoVenta < 0 || $recargoVenta > 100) {
|
||||
$_SESSION['flash_error'] = 'El recargo debe estar entre 0 y 100%.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Guardado de datos de la venta
|
||||
|
||||
$datosExtraVenta = [
|
||||
'forma_pago' => $formaPago,
|
||||
'tipo_pago' => $tipoPago,
|
||||
'descuento' => $descuentoVenta,
|
||||
'recargo' => $recargoVenta,
|
||||
];
|
||||
|
||||
// Requiero los modelos necesarios
|
||||
|
||||
require_once __DIR__ . '/../models/cajaModel.php';
|
||||
$cajamodel = new cajaModel();
|
||||
|
||||
require_once __DIR__ . '/../models/clienteModel.php';
|
||||
$clientemodel = new clienteModel();
|
||||
|
||||
require_once __DIR__ . '/../models/ventaModel.php';
|
||||
$ventamodel = new ventaModel();
|
||||
|
||||
$idCliente = $_SESSION['venta']['cliente']['id'] ?? null;
|
||||
|
||||
if ($idCliente === null) {
|
||||
$_SESSION['flash_error'] = 'No seleccionó un cliente.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
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_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$vendedor) {
|
||||
$_SESSION['flash_error'] = 'No se pudo identificar el usuario.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
$productosFinales = $cajamodel->listarProductos();
|
||||
|
||||
if (empty($productosFinales)) {
|
||||
$_SESSION['flash_error'] = 'No hay productos en la venta.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ($productosFinales as $p) {
|
||||
if (empty($p['id_producto']) || empty($p['cantidad']) || $p['cantidad'] <= 0) {
|
||||
$_SESSION['flash_error'] = 'Venta con productos inválidos.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subtotal que no contiene descuentos.
|
||||
(Al ingresar descuento o recargo, lo guardo en un array separado, para no sobreescribir datos) */
|
||||
|
||||
$subtotal = $cajamodel->calcularSubtotal() ?? 0;
|
||||
$descuento = $cajamodel->calcularDescuentoTotal() ?? 0;
|
||||
|
||||
// Validación del subtotal
|
||||
|
||||
if ($subtotal <= 0) {
|
||||
$_SESSION['flash_error'] = 'La venta no contiene productos válidos.';
|
||||
header('Location: index.php?opt=crear_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Llamamos a la función que devuelve los datos actualizados en un array nuevo
|
||||
|
||||
$datosProvisorios = $ventamodel->actualizarDatosProvisorio($descuentoVenta, $recargoVenta, $subtotal, $descuento);
|
||||
|
||||
if ($datosProvisorios['total'] <= 0) {
|
||||
$_SESSION['flash_error'] = 'El total de la venta es inválido.';
|
||||
header('Location: index.php?opt=resumen_venta');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Obtenemos el ID de venta desde la base de datos
|
||||
|
||||
$idVenta = $ventamodel->guardarVenta($productosFinales, $vendedor, $cliente, $datosExtraVenta, $datosProvisorios);
|
||||
|
||||
// Verificamos si se obtuvo el ID desde la base o si ocurrió un error
|
||||
|
||||
if ($idVenta !== false) {
|
||||
|
||||
// Guardamos en $_SESSION los datos necesarios para la generación del PDF
|
||||
|
||||
$_SESSION['ultima_venta_id'] = $idVenta;
|
||||
|
||||
$_SESSION['venta_pdf'] = [
|
||||
|
||||
'cliente' => $cliente,
|
||||
'vendedor' => $vendedor,
|
||||
'productos' => $productosFinales,
|
||||
|
||||
'cond_iva' => $condIva,
|
||||
'cuit' => $cuit,
|
||||
|
||||
'forma_pago' => $formaPago,
|
||||
'tipo_pago' => $tipoPago,
|
||||
|
||||
'descuentoVenta' => $descuentoVenta,
|
||||
'recargoVenta' => $recargoVenta,
|
||||
|
||||
'descuento' => $datosProvisorios['descuento'],
|
||||
'recargo' => $datosProvisorios['recargo'],
|
||||
|
||||
'subtotal' => $subtotal,
|
||||
'total' => $datosProvisorios['total']
|
||||
];
|
||||
|
||||
// Liberamos
|
||||
|
||||
$cajamodel->vaciarCajaVenta();
|
||||
unset($_SESSION['venta']['cliente']);
|
||||
unset($_SESSION['venta_extra']);
|
||||
unset($_SESSION['venta_final']);
|
||||
unset($_SESSION['prov_venta']);
|
||||
|
||||
$_SESSION['flash_success'] = "Venta guardada correctamente.";
|
||||
|
||||
} else {
|
||||
$_SESSION['flash_error'] = $ventamodel->getError() ?? 'No se pudo guardar la venta.';
|
||||
}
|
||||
|
||||
header("Location: index.php?opt=generar_venta_pdf");
|
||||
exit;
|
||||
|
||||
// LISTAR VENTAS
|
||||
|
||||
case 'listar_ventas':
|
||||
|
||||
// Requiero el modelo de venta
|
||||
|
||||
require_once __DIR__ . '/../models/ventaModel.php';
|
||||
$ventamodel = new ventaModel();
|
||||
|
||||
$anioActual = date('Y');
|
||||
$anioSeleccionado = $_GET['anio'] ?? $anioActual;
|
||||
|
||||
$ventas = $ventamodel->listarVentas($anioSeleccionado);
|
||||
|
||||
foreach ($ventas as $i => $v) {
|
||||
|
||||
// Saneamiento de fecha (para poder ordenar correctamente el campo con dataTables)
|
||||
|
||||
if (!empty($v['fecha'])) {
|
||||
|
||||
$dt = new DateTime($v['fecha']);
|
||||
|
||||
// Para ordenar
|
||||
|
||||
$ventas[$i]['fecha'] = $dt->format('Y-m-d');
|
||||
|
||||
// Para mostrar
|
||||
|
||||
$ventas[$i]['fecha_formateada'] = $dt->format('d/m/Y');
|
||||
|
||||
} else {
|
||||
$ventas[$i]['fecha'] = '-';
|
||||
$ventas[$i]['fecha_formateada'] = '-';
|
||||
}
|
||||
|
||||
// Mapeos de forma y tipo de pago
|
||||
|
||||
$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',
|
||||
];
|
||||
|
||||
// Saneamiento de forma de pago
|
||||
|
||||
$ventas[$i]['forma_pago'] = $mapFormaPago[$ventas[$i]['forma_pago']];
|
||||
|
||||
// Saneamiento de tipo de pago
|
||||
|
||||
$ventas[$i]['tipo_pago'] = $mapTipoPago[$ventas[$i]['tipo_pago']];
|
||||
}
|
||||
|
||||
ob_start();
|
||||
require __DIR__ . '/../views/ventas/listaVentasView.php';
|
||||
return ob_get_clean();
|
||||
|
||||
// MOSTRAR DETALLE DE PRODUCTOS DE UNA VENTA
|
||||
|
||||
case 'detalle_venta':
|
||||
|
||||
$idVenta = (int) ($_GET['id'] ?? 0);
|
||||
|
||||
if ($idVenta <= 0) {
|
||||
$_SESSION['flash_error'] = 'Datos inválidos.';
|
||||
header('Location: index.php?opt=listar_ventas');
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../models/ventaModel.php';
|
||||
$ventamodel = new ventaModel();
|
||||
|
||||
$venta_detalle = $ventamodel->getDetalleVenta($idVenta);
|
||||
|
||||
ob_start();
|
||||
require __DIR__ . '/../views/ventas/ventaDetalleView.php';
|
||||
return ob_get_clean();
|
||||
|
||||
// DEFAULT (404)
|
||||
|
||||
default:
|
||||
|
||||
ob_start();
|
||||
header("Location: index.php?opt=404View.php");
|
||||
return ob_get_clean();
|
||||
}
|
||||
Reference in New Issue
Block a user