Files
whatsapp/modules/turnero/api/get_precios_examenes.php
T
Lizandro GuarnizoandClaude Sonnet 4.6 35cba08004 feat: precios particulares automáticos al seleccionar exámenes
- Sin empresa: usa precio_base de exam_tipos (tarifa particular)
- Panel de precios se muestra con solo seleccionar exámenes (no requiere convenio)
- Total se aplica automáticamente al campo de cobro sin clic manual

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 20:27:18 -05:00

157 lines
5.3 KiB
PHP

<?php
/**
* GET /modules/turnero/api/get_precios_examenes.php
*
* Calcula precios de exámenes según empresa/tarifa.
*
* Query params:
* exam_ids[] int[] IDs de exam_tipos
* nit_empresa string opcional
* subgrupo_id int opcional
*
* Response:
* items[] { exam_tipo_id, codigo, nombre, valor_base, valor_final, tiene_precio }
* subtotal precio antes de descuento empresa
* descuento_pct porcentaje de descuento empresa
* descuento_val valor del descuento
* total total a cobrar
* tarifa_id tarifa aplicada
* tarifa_nombre nombre de la tarifa
*/
require_once __DIR__ . '/_helpers.php';
requireMethod('GET');
$examIds = array_filter(array_map('intval', (array)($_GET['exam_ids'] ?? [])));
$nitEmpresa = trim($_GET['nit_empresa'] ?? '');
$subgrupoId = (int)($_GET['subgrupo_id'] ?? 0);
if (empty($examIds)) jsonOk([
'items' => [],
'subtotal' => 0,
'descuento_pct' => 0,
'descuento_val' => 0,
'total' => 0,
'tarifa_id' => null,
'tarifa_nombre' => null,
]);
$pdo = db();
// ── Resolver tarifa efectiva ───────────────────────────────────
$tarifaId = null;
$tarifaNombre = null;
$descuentoPct = 0;
if ($nitEmpresa !== '') {
$stmtE = $pdo->prepare(
"SELECT e.tarifa_id, e.descuento_pct, ti.nombre AS tarifa_nombre
FROM lab_empresas e
LEFT JOIN lab_tarifas_id ti ON ti.id = e.tarifa_id
WHERE e.nit = ?"
);
$stmtE->execute([$nitEmpresa]);
$empresa = $stmtE->fetch(PDO::FETCH_ASSOC);
if ($empresa) {
$tarifaId = $empresa['tarifa_id'];
$tarifaNombre = $empresa['tarifa_nombre'];
$descuentoPct = (float)$empresa['descuento_pct'];
// Si el subgrupo tiene tarifa propia, override
if ($subgrupoId > 0) {
$stmtS = $pdo->prepare(
"SELECT es.tarifa_id, ti.nombre AS tarifa_nombre
FROM lab_empresa_subgrupos es
LEFT JOIN lab_tarifas_id ti ON ti.id = es.tarifa_id
WHERE es.id = ? AND es.nit_empresa = ? AND es.tarifa_id IS NOT NULL"
);
$stmtS->execute([$subgrupoId, $nitEmpresa]);
$sub = $stmtS->fetch(PDO::FETCH_ASSOC);
if ($sub) {
$tarifaId = $sub['tarifa_id'];
$tarifaNombre = $sub['tarifa_nombre'];
}
}
}
}
// ── Obtener nombre/codigo/precio_base de los exámenes ────────
$ph = implode(',', array_fill(0, count($examIds), '?'));
$stmtX = $pdo->prepare(
"SELECT id AS exam_tipo_id, codigo, nombre, precio_base FROM exam_tipos WHERE id IN ($ph)"
);
$stmtX->execute($examIds);
$examMap = [];
foreach ($stmtX->fetchAll(PDO::FETCH_ASSOC) as $r) {
$examMap[(int)$r['exam_tipo_id']] = $r;
}
// ── Obtener precios desde lab_tarifas (con derivación por %) ──
$items = [];
$subtotal = 0;
foreach ($examIds as $examId) {
$examen = $examMap[$examId] ?? ['codigo' => '?', 'nombre' => 'Desconocido'];
$valorFinal = null;
$valorBase = null;
$tienePrecio = false;
if ($tarifaId !== null) {
// Intentar precio en la tarifa exacta
$stmtP = $pdo->prepare(
"SELECT lt.valor, ti.porcentaje, ti.tarifa_origen,
lt_base.valor AS valor_origen
FROM lab_tarifas lt
JOIN lab_tarifas_id ti ON ti.id = lt.tarifa_id
LEFT JOIN lab_tarifas lt_base ON lt_base.exam_tipo_id = lt.exam_tipo_id
AND lt_base.tarifa_id = ti.tarifa_origen
WHERE lt.exam_tipo_id = ? AND lt.tarifa_id = ?"
);
$stmtP->execute([$examId, $tarifaId]);
$precio = $stmtP->fetch(PDO::FETCH_ASSOC);
if ($precio) {
$tienePrecio = true;
$valorBase = (float)$precio['valor'];
if ((float)$precio['porcentaje'] > 0 && $precio['tarifa_origen'] && $precio['valor_origen'] !== null) {
$valorFinal = round((float)$precio['valor_origen'] * (1 + (float)$precio['porcentaje'] / 100), 0);
} else {
$valorFinal = $valorBase;
}
}
}
// Sin tarifa de empresa: usar precio_base (particular)
if (!$tienePrecio && $examen['precio_base'] !== null && (float)$examen['precio_base'] > 0) {
$tienePrecio = true;
$valorBase = (float)$examen['precio_base'];
$valorFinal = $valorBase;
}
// Si no hay precio, dejar null (sin tarifa o sin mapeo)
$subtotal += $valorFinal ?? 0;
$items[] = [
'exam_tipo_id' => $examId,
'codigo' => $examen['codigo'],
'nombre' => $examen['nombre'],
'valor_base' => $valorBase,
'valor_final' => $valorFinal,
'tiene_precio' => $tienePrecio,
];
}
// ── Aplicar descuento empresa ─────────────────────────────────
$descuentoVal = round($subtotal * $descuentoPct / 100, 0);
$total = $subtotal - $descuentoVal;
jsonOk([
'items' => $items,
'subtotal' => $subtotal,
'descuento_pct' => $descuentoPct,
'descuento_val' => $descuentoVal,
'total' => $total,
'tarifa_id' => $tarifaId,
'tarifa_nombre' => $tarifaNombre,
]);