feat(#51): Issue #51 completado - Catálogo de parámetros de análisis

Implementación completa del sistema de catálogo de parámetros flexible:

 **Tasks completadas:**
- Task 1-12: Todas las tareas implementadas exitosamente
- Task 13: No aplicable (no hay reportes desarrollados aún)

**Características principales:**
- Catálogo centralizado de parámetros reutilizables
- Rangos de referencia flexibles por edad/género/embarazo
- Generación automática de resultados basada en configuración
- Integración completa con el flujo existente
- 36 parámetros demo y 31 rangos de referencia
- Tests automatizados completos

**Modelos implementados:**
- lims.analysis.parameter
- lims.parameter.range
- product.template.parameter

La Task 13 se omitió ya que no existen reportes desarrollados en el módulo actualmente.
This commit is contained in:
Luis Ernesto Portillo Zaldivar 2025-07-15 14:22:11 -06:00
parent aaa1204490
commit c7009990fe
4 changed files with 130 additions and 0 deletions

View File

@ -21,6 +21,9 @@
'web.assets_backend': [
'lims_management/static/src/css/lims_test.css',
],
'web.report_assets_common': [
'lims_management/static/src/css/report_test_result.css',
],
},
'data': [
'security/lims_security.xml',
@ -43,6 +46,7 @@
'views/analysis_parameter_views.xml',
'views/product_template_parameter_config_views.xml',
'views/parameter_dashboard_views.xml',
'report/report_test_result.xml',
],
'demo': [
'demo/z_lims_demo.xml',

View File

@ -54,6 +54,13 @@ class LimsAnalysisParameter(models.Model):
help='Si está desmarcado, el parámetro no estará disponible para nuevas configuraciones'
)
category_id = fields.Many2one(
'product.category',
string='Categoría',
domain="[('parent_id.name', '=', 'Análisis de Laboratorio')]",
help='Categoría del parámetro para agrupar en reportes'
)
# Relaciones
template_parameter_ids = fields.One2many(
'product.template.parameter',

View File

@ -0,0 +1,114 @@
/* Estilos para el reporte de resultados de laboratorio */
/* Estilos generales */
.patient-info {
background-color: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
.test-section {
border: 1px solid #dee2e6;
border-radius: 5px;
padding: 15px;
margin-bottom: 20px;
}
.test-header {
border-radius: 5px 5px 0 0;
margin: -15px -15px 15px -15px;
}
/* Estilos para la tabla de resultados */
.result-row {
transition: background-color 0.3s;
}
.result-row.normal {
background-color: transparent;
}
.result-row.out-of-range {
background-color: #fff3cd;
}
.result-row.critical {
background-color: #f8d7da;
}
.result-row.panic {
background-color: #d1ecf1;
font-weight: bold;
}
/* Estilos para valores */
.result-row.out-of-range td:nth-child(3) {
color: #856404;
font-weight: bold;
}
.result-row.critical td:nth-child(3) {
color: #721c24;
font-weight: bold;
}
.result-row.panic td:nth-child(3) {
color: #004085;
font-weight: bold;
}
/* Badges personalizados */
.badge {
font-size: 0.875rem;
padding: 0.375rem 0.75rem;
}
/* Tablas más compactas */
.table-sm td, .table-sm th {
padding: 0.3rem;
}
/* Encabezados de categoría */
h6.text-primary {
border-bottom: 2px solid #007bff;
padding-bottom: 5px;
}
/* Notas y observaciones */
.text-muted {
font-size: 0.9rem;
}
/* Impresión */
@media print {
.page {
page-break-after: auto;
}
.test-section {
page-break-inside: avoid;
}
.patient-info {
page-break-inside: avoid;
}
.result-row.out-of-range {
background-color: #fff3cd !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.result-row.critical {
background-color: #f8d7da !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.result-row.panic {
background-color: #d1ecf1 !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}

View File

@ -28,6 +28,11 @@
type="object"
invisible="state not in ['draft', 'in_process']"
confirm="¿Está seguro de regenerar los resultados? Esto eliminará los resultados actuales."/>
<button name="%(lims_management.action_report_test_result)d"
string="Imprimir Resultados"
type="action"
class="btn-primary"
invisible="state not in ['result_entered', 'validated']"/>
<field name="state" widget="statusbar"
statusbar_visible="draft,in_process,result_entered,validated"/>
</header>