This commit is contained in:
2025-07-09 16:14:22 -06:00
parent 91b6806898
commit 287ad27274
39 changed files with 2517 additions and 2000 deletions

View File

@@ -2,9 +2,11 @@
require_once __DIR__ . '/../helpers/session.php';
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../helpers/env.php';
ob_clean();
function guardar() {
function guardar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
@@ -12,30 +14,27 @@ function guardar() {
$conn = getConnection();
// Capturar campos del formulario
$clave = $_POST['clave'];
$nombre = $_POST['nombre'];
$rfc = $_POST['rfc'];
$curp = $_POST['curp'] ?? null;
$dom = $_POST['domicilio'];
$pais = $_POST['pais'];
$entidad = $_POST['entidad'];
$ciudad = $_POST['ciudad'];
$tel = $_POST['telefono'];
$caat = $_POST['caat'];
$usr_id = $_SESSION['usuario_id'];
$clave = $_POST['clave'];
$nombre = $_POST['nombre'];
$rfc = $_POST['rfc'];
$curp = $_POST['curp'] ?? null;
$dom = $_POST['domicilio'];
$pais = $_POST['pais'];
$entidad = $_POST['entidad'];
$ciudad = $_POST['ciudad'];
$tel = $_POST['telefono'];
$caat = $_POST['caat'];
$usr_id = $_SESSION['usuario_id'];
// INSERT incluyendo id_usuario
$sql = "INSERT INTO dbo.transportistas
(clave_identificador, nombre, rfc, curp, domicilio, pais,
entidad_federativa, ciudad, telefono, caat, id_usuario)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$params = [
$clave, $nombre, $rfc, $curp, $dom,
$pais, $entidad, $ciudad, $tel, $caat,
$usr_id
];
$sql = "INSERT INTO dbo.transportistas
(clave_identificador, nombre, rfc, curp, domicilio, pais,
entidad_federativa, ciudad, telefono, caat, id_usuario)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
";
$params = [$clave, $nombre, $rfc, $curp, $dom, $pais, $entidad, $ciudad, $tel, $caat, $usr_id];
$stmt = sqlsrv_query($conn, $sql, $params);
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al guardar transportista: " . print_r(sqlsrv_errors(), true));
}
@@ -45,11 +44,14 @@ function guardar() {
exit;
}
function alta() {
function alta()
{
$conn = getConnection();
// 1) Cargar países
$sql = "SELECT id_pais, nombre FROM paises ORDER BY nombre";
$sql = "SELECT id_pais, nombre FROM paises ORDER BY nombre";
$stmt = sqlsrv_query($conn, $sql);
$paises = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$paises[] = $row;
@@ -59,48 +61,69 @@ function alta() {
}
// AJAX: devuelve los estados de un país dado
function estados() {
function estados()
{
header('Content-Type: application/json; charset=utf-8');
$pais = $_GET['pais'] ?? '';
$conn = getConnection();
$sql = "SELECT id_estado, nombre FROM estados WHERE pais_id = ? ORDER BY nombre";
$sql = "SELECT id_estado, nombre FROM estados WHERE pais_id = ? ORDER BY nombre";
$stmt = sqlsrv_query($conn, $sql, [$pais]);
$out = [];
while ($r = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$out[] = $r;
}
echo json_encode($out);
exit;
}
// AJAX: devuelve las ciudades de un estado dado
function ciudades() {
function ciudades()
{
header('Content-Type: application/json; charset=utf-8');
$estado = $_GET['estado'] ?? '';
$conn = getConnection();
$sql = "SELECT id_ciudad, nombre FROM ciudades WHERE estado_id = ? ORDER BY nombre";
$sql = "SELECT id_ciudad, nombre FROM ciudades WHERE estado_id = ? ORDER BY nombre";
$stmt = sqlsrv_query($conn, $sql, [$estado]);
$out = [];
while ($r = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$out[] = $r;
}
echo json_encode($out);
exit;
}
function lista()
{
// 1) Verificar sesión
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/transportistas/lista.php';
}
/** Descarga la plantilla CSV para carga masiva **/
function template() {
function template()
{
$file = __DIR__ . '/../../public/downloads/transportistas_template.csv';
if (!file_exists($file)) {
http_response_code(404);
echo "❌ Plantilla no encontrada.";
exit;
}
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="transportistas_template.csv"');
readfile($file);
@@ -108,18 +131,22 @@ function template() {
}
/** Procesa la carga masiva desde un CSV **/
function importar() {
function importar()
{
// 1) Verificar sesión
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$usr_id = $_SESSION['usuario_id'];
// 2) Validar archivo subido
if (!isset($_FILES['archivo_csv']) || $_FILES['archivo_csv']['error'] !== UPLOAD_ERR_OK) {
die("❌ Debes subir un archivo CSV válido.");
}
$ext = pathinfo($_FILES['archivo_csv']['name'], PATHINFO_EXTENSION);
if (strtolower($ext) !== 'csv') {
die("❌ Solo se permiten archivos .csv");
}
@@ -132,17 +159,15 @@ function importar() {
// 4) Encabezados esperados
$header = fgetcsv($fh, 1000, ',');
$expected = [
'clave_identificador','nombre','rfc','curp',
'telefono','caat','pais_id','estado_id',
'ciudad_id','domicilio'
];
$expected = ['clave_identificador', 'nombre', 'rfc', 'curp', 'telefono', 'caat', 'pais_id', 'estado_id', 'ciudad_id', 'domicilio'];
if ($header === false || array_map('trim', $header) !== $expected) {
fclose($fh);
die("❌ Encabezado de CSV inválido. Debe contener: " . implode(',', $expected));
}
$conn = getConnection();
$errors = [];
$rowNum = 1;
@@ -154,7 +179,7 @@ function importar() {
continue;
}
// mapear valores y trim
list($clave,$nombre,$rfc,$curp,$tel,$caat,$pais_id,$estado_id,$ciudad_id,$dom) = array_map('trim', $row);
list($clave, $nombre, $rfc, $curp, $tel, $caat, $pais_id, $estado_id, $ciudad_id, $dom) = array_map('trim', $row);
// validar obligatorios
if ($clave==='' || $nombre==='' || $rfc==='' || $tel==='' || $caat===''
@@ -164,13 +189,14 @@ function importar() {
}
// Convertir IDs a nombres
$pais_nombre = '';
$pais_nombre = '';
$estado_nombre = '';
$ciudad_nombre = '';
// Consultar nombre del país
$sql = "SELECT nombre FROM dbo.paises WHERE id_pais = ?";
$sql = "SELECT nombre FROM dbo.paises WHERE id_pais = ?";
$stmt = sqlsrv_query($conn, $sql, [$pais_id]);
if ($row_pais = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$pais_nombre = $row_pais['nombre'];
} else {
@@ -179,8 +205,9 @@ function importar() {
}
// Consultar nombre del estado
$sql = "SELECT nombre FROM dbo.estados WHERE id_estado = ?";
$sql = "SELECT nombre FROM dbo.estados WHERE id_estado = ?";
$stmt = sqlsrv_query($conn, $sql, [$estado_id]);
if ($row_estado = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$estado_nombre = $row_estado['nombre'];
} else {
@@ -189,8 +216,9 @@ function importar() {
}
// Consultar nombre de la ciudad
$sql = "SELECT nombre FROM dbo.ciudades WHERE id_ciudad = ?";
$sql = "SELECT nombre FROM dbo.ciudades WHERE id_ciudad = ?";
$stmt = sqlsrv_query($conn, $sql, [$ciudad_id]);
if ($row_ciudad = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$ciudad_nombre = $row_ciudad['nombre'];
} else {
@@ -199,16 +227,14 @@ function importar() {
}
// 5) Insertar en BD con nombres
$sql = "INSERT INTO dbo.transportistas
(clave_identificador, nombre, rfc, curp, telefono, caat,
pais, entidad_federativa, ciudad, domicilio, id_usuario)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$params = [
$clave, $nombre, $rfc, $curp, $tel,
$caat, $pais_nombre, $estado_nombre, $ciudad_nombre, $dom,
$usr_id
];
$stmt = sqlsrv_query($conn, $sql, $params);
$sql = "INSERT INTO dbo.transportistas
(clave_identificador, nombre, rfc, curp, telefono, caat,
pais, entidad_federativa, ciudad, domicilio, id_usuario)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
";
$params = [$clave, $nombre, $rfc, $curp, $tel, $caat, $pais_nombre, $estado_nombre, $ciudad_nombre, $dom, $usr_id];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
$errors[] = "Fila $rowNum: error al guardar → " . print_r(sqlsrv_errors(), true);
}
@@ -226,89 +252,87 @@ function importar() {
exit;
}
function bulk_upload() {
function bulk_upload()
{
include __DIR__ . '/../../views/transportistas/bulk_upload.php';
}
function ajax_lista() {
function ajax_lista()
{
// 1) Autorización
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode([]);
exit;
}
$usr = $_SESSION['usuario_id'];
$conn = getConnection();
// 2) Parámetros de DataTables
$draw = intval($_GET['draw'] ?? 0);
$start = intval($_GET['start'] ?? 0);
$length = intval($_GET['length'] ?? 10);
$draw = intval($_GET['draw'] ?? 0);
$start = intval($_GET['start'] ?? 0);
$length = intval($_GET['length'] ?? 10);
$search = $_GET['search']['value'] ?? '';
// Mapeo columnas - ahora incluimos el nombre de la ciudad
$cols = ['t.id_transportista','t.clave_identificador','t.nombre','t.rfc','c.nombre','t.creado_en'];
$orderColIdx = intval($_GET['order'][0]['column'] ?? 5);
$cols = ['t.id_transportista', 't.clave_identificador', 't.nombre', 't.rfc', 'c.nombre', 't.creado_en'];
$orderColIdx = intval($_GET['order'][0]['column'] ?? 5);
$orderDir = strtoupper($_GET['order'][0]['dir'] ?? 'ASC') === 'DESC' ? 'DESC' : 'ASC';
$orderCol = in_array($orderColIdx, range(0,5)) ? $cols[$orderColIdx] : 't.creado_en';
$orderCol = in_array($orderColIdx, range(0,5)) ? $cols[$orderColIdx] : 't.creado_en';
// 3) Total registros sin filtro
$sqlTotal = "SELECT COUNT(*) AS total FROM dbo.transportistas WHERE id_usuario = ? AND activo = 1";
$stmt = sqlsrv_query($conn, $sqlTotal, [$usr]);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
$sqlTotal = "SELECT COUNT(*) AS total FROM dbo.transportistas WHERE id_usuario = ? AND activo = 1";
$stmt = sqlsrv_query($conn, $sqlTotal, [$usr]);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
$recordsTotal = (int)$row['total'];
// 4) Construir condiciones de filtro
$where = "t.id_usuario = ? AND t.activo = 1 ";
$where = "t.id_usuario = ? AND t.activo = 1 ";
$params = [$usr];
if ($search !== '') {
$where .= " AND (
t.nombre LIKE ? OR
t.rfc LIKE ? OR
c.nombre LIKE ?
)";
$like = "%{$search}%";
$where .= " AND (t.nombre LIKE ? OR t.rfc LIKE ? OR c.nombre LIKE ?)";
$like = "%{$search}%";
$params = array_merge($params, array_fill(0, 3, $like));
}
// 5) Total registros filtrados (CON JOIN)
$sqlFiltered = "
SELECT COUNT(*) AS total
FROM dbo.transportistas t
LEFT JOIN dbo.ciudades c ON t.ciudad = c.id_ciudad
LEFT JOIN dbo.estados e ON c.estado_id = e.id_estado
LEFT JOIN dbo.paises p ON e.pais_id = p.id_pais
WHERE $where
";
$stmtF = sqlsrv_query($conn, $sqlFiltered, $params);
$rowF = sqlsrv_fetch_array($stmtF, SQLSRV_FETCH_ASSOC);
$sqlFiltered = "SELECT COUNT(*) AS total
FROM dbo.transportistas t
LEFT JOIN dbo.ciudades c
ON t.ciudad = c.id_ciudad
LEFT JOIN dbo.estados e
ON c.estado_id = e.id_estado
LEFT JOIN dbo.paises p
ON e.pais_id = p.id_pais
WHERE $where
";
$stmtF = sqlsrv_query($conn, $sqlFiltered, $params);
$rowF = sqlsrv_fetch_array($stmtF, SQLSRV_FETCH_ASSOC);
$recordsFiltered = (int)$rowF['total'];
// 6) Datos de la página con JOIN completo
$sqlData = "
SELECT t.id_transportista,
t.clave_identificador,
t.nombre,
t.rfc,
COALESCE(c.nombre, 'Ciudad no encontrada') as ciudad_nombre,
COALESCE(e.nombre, '') as estado_nombre,
COALESCE(p.nombre, '') as pais_nombre,
t.creado_en
FROM dbo.transportistas t
LEFT JOIN dbo.ciudades c ON t.ciudad = c.id_ciudad
LEFT JOIN dbo.estados e ON c.estado_id = e.id_estado
LEFT JOIN dbo.paises p ON e.pais_id = p.id_pais
WHERE $where
ORDER BY $orderCol $orderDir
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY
";
// agregar offset/limit al final
$sqlData = "SELECT
t.id_transportista, t.clave_identificador, t.nombre, t.rfc, t.creado_en,
COALESCE(c.nombre, 'Ciudad no encontrada') as ciudad_nombre,
COALESCE(e.nombre, '') as estado_nombre,
COALESCE(p.nombre, '') as pais_nombre
FROM dbo.transportistas t
LEFT JOIN dbo.ciudades c
ON t.ciudad = c.id_ciudad
LEFT JOIN dbo.estados e
ON c.estado_id = e.id_estado
LEFT JOIN dbo.paises p
ON e.pais_id = p.id_pais
WHERE $where
ORDER BY $orderCol $orderDir
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY
"; // Agregar offset/limit al final
$params[] = $start;
$params[] = $length;
$stmtD = sqlsrv_query($conn, $sqlData, $params);
$stmtD = sqlsrv_query($conn, $sqlData, $params);
$data = [];
while ($r = sqlsrv_fetch_array($stmtD, SQLSRV_FETCH_ASSOC)) {
@@ -345,16 +369,19 @@ function ajax_lista() {
exit;
}
function editar() {
function editar()
{
// 1) Verificar sesión
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$usr = $_SESSION['usuario_id'];
// 2) Obtener el ID y validarlo
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID de transportista inválido.");
}
@@ -362,9 +389,9 @@ function editar() {
$conn = getConnection();
// 3) Consultar el transportista (pertenece al usuario)
$sql = "SELECT * FROM dbo.transportistas
WHERE id_transportista = ? AND id_usuario = ?";
$sql = "SELECT * FROM dbo.transportistas WHERE id_transportista = ? AND id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$id, $usr]);
$t = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$t) {
die("❌ Transportista no encontrado o no autorizado.");
@@ -402,20 +429,21 @@ function actualizar()
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$usr = $_SESSION['usuario_id'];
// 1) Capturar y validar datos
$id = $_POST['id_transportista'] ?? null;
$clave = trim($_POST['clave'] ?? '');
$nombre= trim($_POST['nombre'] ?? '');
$rfc = trim($_POST['rfc'] ?? '');
$curp = trim($_POST['curp'] ?? '');
$tel = trim($_POST['telefono'] ?? '');
$caat = trim($_POST['caat'] ?? '');
$pais = $_POST['pais'] ?? '';
$estado= $_POST['entidad'] ?? '';
$ciudad= $_POST['ciudad'] ?? '';
$dom = trim($_POST['domicilio'] ?? '');
$id = $_POST['id_transportista'] ?? null;
$clave = trim($_POST['clave'] ?? '');
$nombre = trim($_POST['nombre'] ?? '');
$rfc = trim($_POST['rfc'] ?? '');
$curp = trim($_POST['curp'] ?? '');
$tel = trim($_POST['telefono'] ?? '');
$caat = trim($_POST['caat'] ?? '');
$pais = $_POST['pais'] ?? '';
$estado = $_POST['entidad'] ?? '';
$ciudad = $_POST['ciudad'] ?? '';
$dom = trim($_POST['domicilio'] ?? '');
if (!$id || !is_numeric($id)
|| $clave===''||$nombre===''||$rfc===''||$tel===''||$caat===''
@@ -427,33 +455,29 @@ function actualizar()
$conn = getConnection();
// 2) Verificar que exista y pertenezca al usuario
$sqlChk = "SELECT COUNT(*) AS cnt
FROM dbo.transportistas
WHERE id_transportista = ? AND id_usuario = ?";
$sqlChk = "SELECT COUNT(*) AS cnt FROM dbo.transportistas WHERE id_transportista = ? AND id_usuario = ?";
$stmtChk = sqlsrv_query($conn, $sqlChk, [$id, $usr]);
$rowChk = sqlsrv_fetch_array($stmtChk, SQLSRV_FETCH_ASSOC);
$rowChk = sqlsrv_fetch_array($stmtChk, SQLSRV_FETCH_ASSOC);
if ($rowChk['cnt'] == 0) {
die("❌ Transportista no encontrado o no autorizado.");
}
// 3) Ejecutar UPDATE
$sqlUpd = "UPDATE dbo.transportistas SET
clave_identificador = ?,
nombre = ?,
rfc = ?,
curp = ?,
telefono = ?,
caat = ?,
pais = ?,
entidad_federativa = ?,
ciudad = ?,
domicilio = ?
WHERE id_transportista = ?";
$params = [
$clave, $nombre, $rfc, $curp, $tel,
$caat, $pais, $estado, $ciudad, $dom,
$id
];
$sqlUpd = "UPDATE dbo.transportistas SET
clave_identificador = ?,
nombre = ?,
rfc = ?,
curp = ?,
telefono = ?,
caat = ?,
pais = ?,
entidad_federativa = ?,
ciudad = ?,
domicilio = ?
WHERE id_transportista = ?
";
$params = [$clave, $nombre, $rfc, $curp, $tel, $caat, $pais, $estado, $ciudad, $dom, $id];
$stmtUpd = sqlsrv_query($conn, $sqlUpd, $params);
if ($stmtUpd === false) {
die("❌ Error al actualizar: " . print_r(sqlsrv_errors(), true));
@@ -464,13 +488,16 @@ function actualizar()
exit;
}
function eliminar() {
function eliminar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$usr = $_SESSION['usuario_id'];
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
@@ -478,18 +505,18 @@ function eliminar() {
$conn = getConnection();
// Verificar que el transportista exista y pertenezca al usuario
$sqlChk = "SELECT COUNT(*) AS cnt
FROM dbo.transportistas
WHERE id_transportista = ? AND id_usuario = ?";
$sqlChk = "SELECT COUNT(*) AS cnt FROM dbo.transportistas WHERE id_transportista = ? AND id_usuario = ?";
$stmtChk = sqlsrv_query($conn, $sqlChk, [$id, $usr]);
$rowChk = sqlsrv_fetch_array($stmtChk, SQLSRV_FETCH_ASSOC);
if ($rowChk['cnt'] == 0) {
die("❌ Transportista no encontrado o no autorizado.");
}
// ELIMINACIÓN REAL - DELETE en lugar de UPDATE
$sqlDel = "UPDATE dbo.transportistas SET activo = 0 WHERE id_transportista = ?";
$sqlDel = "UPDATE dbo.transportistas SET activo = 0 WHERE id_transportista = ?";
$stmtDel = sqlsrv_query($conn, $sqlDel, [$id]);
if ($stmtDel === false) {
die("❌ Error al eliminar: " . print_r(sqlsrv_errors(), true));
}