Files
whatsapp/api/lab/empresas.php
T
Lizandro GuarnizoandClaude Sonnet 4.6 b9bb4fc628 feat(lab_empresas): módulo CRUD de empresas, convenios y tarifas
- Nuevo módulo lab_empresas: lista paginada, modal create/edit empresa,
  gestión de subgrupos inline y CRUD de catálogo lab_tarifas_id
- APIs: empresas.php (list/get/save/toggle/delete),
  empresa_subgrupos.php, tarifas_id.php
- Migración 09 registra el módulo en system_modules y asigna permiso admin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-04 22:05:14 -05:00

163 lines
6.7 KiB
PHP

<?php
/**
* /api/lab/empresas.php
*
* GET ?action=list [search, activa, page, limit] → lista paginada
* GET ?action=get &nit= → empresa + subgrupos
* POST {action:save, nit, nombre, ...} → upsert empresa
* POST {action:toggle, nit} → activa/inactiva
* POST {action:delete, nit} → elimina (si sin recepciones)
*/
require_once __DIR__ . '/_helpers.php';
$method = $_SERVER['REQUEST_METHOD'];
// ─── GET ─────────────────────────────────────────────────────────────────────
if ($method === 'GET') {
$action = $_GET['action'] ?? 'list';
$pdo = db();
if ($action === 'get') {
$nit = trim($_GET['nit'] ?? '');
if ($nit === '') jsonError('nit requerido');
$e = $pdo->prepare(
"SELECT e.*, ti.nombre AS tarifa_nombre
FROM lab_empresas e
LEFT JOIN lab_tarifas_id ti ON ti.id = e.tarifa_id
WHERE e.nit = ?"
);
$e->execute([$nit]);
$empresa = $e->fetch(PDO::FETCH_ASSOC);
if (!$empresa) jsonError('Empresa no encontrada', 404);
$s = $pdo->prepare(
"SELECT es.*, ti.nombre AS tarifa_nombre
FROM lab_empresa_subgrupos es
LEFT JOIN lab_tarifas_id ti ON ti.id = es.tarifa_id
WHERE es.nit_empresa = ?
ORDER BY es.subgrupo ASC"
);
$s->execute([$nit]);
$empresa['subgrupos'] = $s->fetchAll(PDO::FETCH_ASSOC);
jsonOk(['empresa' => $empresa]);
}
// list
$search = trim($_GET['search'] ?? '');
$activa = isset($_GET['activa']) && $_GET['activa'] !== '' ? (int)$_GET['activa'] : null;
$page = max(1, (int)($_GET['page'] ?? 1));
$limit = max(1, min(100, (int)($_GET['limit'] ?? 30)));
$offset = ($page - 1) * $limit;
$where = [];
$params = [];
if ($search !== '') {
$where[] = '(e.nombre LIKE ? OR e.nit LIKE ? OR e.razon_social LIKE ?)';
$like = "%{$search}%";
$params[] = $like; $params[] = $like; $params[] = $like;
}
if ($activa !== null) {
$where[] = 'e.activa = ?';
$params[] = $activa;
}
$wSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';
$total = $pdo->prepare("SELECT COUNT(*) FROM lab_empresas e $wSql");
$total->execute($params);
$totalRows = (int)$total->fetchColumn();
$rows = $pdo->prepare(
"SELECT e.nit, e.nombre, e.razon_social, e.tarifa_id, ti.nombre AS tarifa_nombre,
e.descuento_pct, e.codigo_eps, e.tipo_usuario, e.req_autoriza, e.activa,
(SELECT COUNT(*) FROM lab_empresa_subgrupos es WHERE es.nit_empresa = e.nit) AS total_subgrupos
FROM lab_empresas e
LEFT JOIN lab_tarifas_id ti ON ti.id = e.tarifa_id
$wSql
ORDER BY e.nombre ASC
LIMIT $limit OFFSET $offset"
);
$rows->execute($params);
jsonOk([
'empresas' => $rows->fetchAll(PDO::FETCH_ASSOC),
'total' => $totalRows,
'page' => $page,
'limit' => $limit,
'pages' => (int)ceil($totalRows / $limit),
]);
}
// ─── POST ────────────────────────────────────────────────────────────────────
requireMethod('POST');
$data = json_decode(file_get_contents('php://input'), true) ?? [];
$action = $data['action'] ?? '';
$pdo = db();
if ($action === 'toggle') {
$nit = trim($data['nit'] ?? '');
if ($nit === '') jsonError('nit requerido');
$pdo->prepare("UPDATE lab_empresas SET activa = 1 - activa WHERE nit = ?")->execute([$nit]);
$activa = (int)$pdo->prepare("SELECT activa FROM lab_empresas WHERE nit=?")->execute([$nit]);
$row = $pdo->prepare("SELECT activa FROM lab_empresas WHERE nit=?");
$row->execute([$nit]);
jsonOk(['activa' => (bool)(int)$row->fetchColumn()]);
}
if ($action === 'delete') {
$nit = trim($data['nit'] ?? '');
if ($nit === '') jsonError('nit requerido');
// Block deletion if empresa has recepciones (historical)
$chk = $pdo->prepare("SELECT COUNT(*) FROM lab_recepciones WHERE nit_empresa = ? LIMIT 1");
$chk->execute([$nit]);
if ((int)$chk->fetchColumn() > 0) {
jsonError('No se puede eliminar: la empresa tiene recepciones históricas registradas.', 409);
}
$pdo->prepare("DELETE FROM lab_empresas WHERE nit = ?")->execute([$nit]);
jsonOk(['deleted' => true]);
}
if ($action === 'save') {
$nit = trim($data['nit'] ?? '');
$nombre = trim($data['nombre'] ?? '');
if ($nit === '') jsonError('El NIT es obligatorio');
if ($nombre === '') jsonError('El nombre es obligatorio');
$fields = [
'nombre' => $nombre,
'razon_social' => trim($data['razon_social'] ?? '') ?: null,
'tarifa_id' => isset($data['tarifa_id']) && $data['tarifa_id'] !== '' ? (int)$data['tarifa_id'] : null,
'descuento_pct' => isset($data['descuento_pct']) ? (float)$data['descuento_pct'] : 0,
'codigo_eps' => trim($data['codigo_eps'] ?? '') ?: null,
'tipo_usuario' => trim($data['tipo_usuario'] ?? '') ?: null,
'tipo_usuario_sispro'=> trim($data['tipo_usuario_sispro']?? '') ?: null,
'cod_contrato' => trim($data['cod_contrato'] ?? '') ?: null,
'cod_tercero' => trim($data['cod_tercero'] ?? '') ?: null,
'centro_costo' => trim($data['centro_costo'] ?? '') ?: null,
'req_autoriza' => isset($data['req_autoriza']) ? (int)(bool)$data['req_autoriza'] : 0,
'activa' => isset($data['activa']) ? (int)(bool)$data['activa'] : 1,
];
// Check if exists
$exists = $pdo->prepare("SELECT nit FROM lab_empresas WHERE nit = ?");
$exists->execute([$nit]);
$isNew = !$exists->fetch();
if ($isNew) {
$cols = implode(', ', array_map(fn($k) => "`$k`", array_keys($fields)));
$ph = implode(', ', array_fill(0, count($fields), '?'));
$pdo->prepare("INSERT INTO lab_empresas (nit, $cols) VALUES (?, $ph)")
->execute(array_merge([$nit], array_values($fields)));
} else {
$sets = implode(', ', array_map(fn($k) => "`$k` = ?", array_keys($fields)));
$pdo->prepare("UPDATE lab_empresas SET $sets WHERE nit = ?")
->execute(array_merge(array_values($fields), [$nit]));
}
jsonOk(['nit' => $nit, 'created' => $isNew]);
}
jsonError('Acción no reconocida', 400);