feat(#51): Task 4 completada - Agregar método _compute_age() en res.partner

- Agregado campo computado 'age' que calcula edad en años desde birthdate_date
- Agregado campo 'is_pregnant' con validación de género femenino
- Implementado método _compute_age() usando relativedelta para precisión
- Agregado método helper get_age_at_date() para cálculos en fechas específicas
- Actualizada vista de pacientes para mostrar edad y estado de embarazo
- Validación que previene marcar embarazo en género masculino

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Luis Ernesto Portillo Zaldivar 2025-07-15 11:56:50 -06:00
parent bd0daf3da7
commit 99990bdfcc
3 changed files with 61 additions and 0 deletions

View File

@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
from odoo.exceptions import ValidationError
from datetime import date
from dateutil.relativedelta import relativedelta
class ResPartner(models.Model):
_inherit = 'res.partner'
@ -17,6 +20,19 @@ class ResPartner(models.Model):
('female', 'Femenino'),
('other', 'Otro')
], string="Género")
# Nuevos campos para el cálculo de rangos
age = fields.Integer(
string="Edad",
compute='_compute_age',
store=False,
help="Edad calculada en años basada en la fecha de nacimiento"
)
is_pregnant = fields.Boolean(
string="Embarazada",
help="Marcar si la paciente está embarazada (solo aplica para género femenino)"
)
is_doctor = fields.Boolean(string="Es Médico")
doctor_license = fields.Char(string="Licencia Médica", copy=False)
@ -25,6 +41,25 @@ class ResPartner(models.Model):
('patient_identifier_unique', 'unique(patient_identifier)', 'El identificador del paciente debe ser único.'),
('doctor_license_unique', 'unique(doctor_license)', 'La licencia médica debe ser única.')
]
@api.depends('birthdate_date')
def _compute_age(self):
"""Calcula la edad en años basada en la fecha de nacimiento"""
today = date.today()
for partner in self:
if partner.birthdate_date:
# Calcular diferencia usando relativedelta para precisión
delta = relativedelta(today, partner.birthdate_date)
partner.age = delta.years
else:
partner.age = 0
@api.constrains('is_pregnant', 'gender')
def _check_pregnant_gender(self):
"""Valida que solo pacientes de género femenino puedan estar embarazadas"""
for partner in self:
if partner.is_pregnant and partner.gender != 'female':
raise ValidationError('Solo las pacientes de género femenino pueden estar marcadas como embarazadas.')
@api.model_create_multi
def create(self, vals_list):
@ -32,3 +67,25 @@ class ResPartner(models.Model):
if vals.get('is_patient') and not vals.get('patient_identifier'):
vals['patient_identifier'] = self.env['ir.sequence'].next_by_code('res.partner.patient_identifier')
return super(ResPartner, self).create(vals_list)
def get_age_at_date(self, target_date=None):
"""
Calcula la edad del paciente en una fecha específica.
:param target_date: Fecha en la que calcular la edad. Si es None, usa la fecha actual.
:return: Edad en años
"""
self.ensure_one()
if not self.birthdate_date:
return 0
if not target_date:
target_date = date.today()
elif isinstance(target_date, str):
target_date = fields.Date.from_string(target_date)
if target_date < self.birthdate_date:
return 0
delta = relativedelta(target_date, self.birthdate_date)
return delta.years

View File

@ -11,6 +11,8 @@
<field name="name"/>
<field name="gender"/>
<field name="birthdate_date"/>
<field name="age" optional="show"/>
<field name="is_pregnant" optional="show"/>
</list>
</field>
</record>
@ -43,7 +45,9 @@
<field name="patient_identifier" invisible="not is_patient" readonly="patient_identifier"/>
<field name="origin" readonly="id" invisible="not is_patient"/>
<field name="birthdate_date" invisible="not is_patient"/>
<field name="age" invisible="not is_patient or not birthdate_date"/>
<field name="gender" invisible="not is_patient"/>
<field name="is_pregnant" invisible="not is_patient or gender != 'female'"/>
</group>
<group>
<field name="is_doctor"/>