Buenas tardes desde España,
¿Qué tal tod@s? Bien, procedo a hacer una descripción de mi caso para saber que error cometo. Estoy creando un módulo desde cero en Odoo 8 a medida de lo que pide el cliente. Entonces los campos que son dedicados a telefono no quiero que admitan otra cosa que sea números. Pero son de tipo Char debido a que Odoo 8.0.0.1 no permite limitar los campos Integer. Aquí en España los telefonos tienen 9 digitos de longitud. Entonces procedo con el código Python:
# -*- coding: utf-8 -*-
# importamos modulos
from openerp import models, fields, api
# Clase declara el modelo de la base de datos del modulo para construirlo al instalarse
class admision(models.Model):
# llamo al modelo
_name = 'admision.ingreso'
# aqui van las funciones y campos
#Declaro el ID de la tabla del modulo en python para que SQL pueda darlo como primary key
id = fields.Integer(string ='Numero de ingreso', readonly=True)
# bloque 1: datos paciente
Nombre = fields.Char(string='Nombre',size=60,required=True)
Apellidos = fields.Char(string='Apellidos',size=60, required=True)
Nif = fields.Char(string='NIF',size=30, required=True)
Fecha_Nacimiento = fields.Date(string='Fecha de nacimiento',required=True)
Direccion_Paciente = fields.Char(string='Dirección del paciente', size=100,required=True)
Poblacion_Paciente = fields.Char(string='Población del paciente', size=60 ,required=True)
Provincia_Paciente = fields.Char(string='Provincia del paciente', size=60 ,required=True)
# en el archivo XML este bloque se divide en dos
CP_Paciente = fields.Char(string='CP del paciente', size= 6 ,required=True)
Telefono1_Paciente = fields.Char(string='Telefono fijo paciente', size=9 ,required=True)
Telefono2_Paciente = fields.Char(string='Telefono movil paciente', size=9 ,required=True)
Email2_Paciente = fields.Char(string='Email del paciente', size=60,required=True)
Paciente_Activo = fields.Boolean(string='Paciente activo')
Capacitado_Legalmente = fields.Boolean(string='Capacitado legalmente')
Fecha_Contacto = fields.Date(string='Fecha de contacto',required=True)
Fecha_Actualizacion = fields.Date(string='Fecha de actualización')
# Aquí va datos tabla de tutores y titulares
Nombre_Tutor_Legal = fields.Char(string='Nombre del tutor', size=60)
Apellido_Tutor_Legal = fields.Char(string='Apellido del tutor', size=60)
Nif_Tutor_Legal = fields.Char(string='NIF del tutor', size=30)
Direccion = fields.Char(string='Dirección del tutor', size=100)
Poblacion = fields.Char(string='Población del tutor', size=60)
Provincia = fields.Char(string='Provincia del tutor', size=60 )
CP = fields.Char(string='Código postal', size=6)
Titular_Telefono1 = fields.Char(string='Telefono fijo tutor', size=9)
Titular_Telefono2 = fields.Char(string='Telefono movil tutor', size=9)
Titular_Email1 = fields.Char(string='Email titular 1', size=60)
Titular_Email2 = fields.Char(string='Email titular 2', size=60)
# datos de los familiares
Nif_Padre = fields.Char(string='NIF del padre',size=30)
Nif_Madre = fields.Char(string='NIF del madre', size=30)
Mail1 = fields.Char(string='email 1', size=60)
Mail2 = fields.Char(string='email 2', size=60)
Telefono1 = fields.Char(string='Telefono fijo', size=9)
Telefono2 = fields.Char(string='Telefono movil', size=9)
# campos descriptivos
Tipo_Lesion = fields.Text(string='Tipo de lesión', size=150,required=True)
Conocenos = fields.Text(string='Conocenos', size=60)
# aquí viene decorador función para que solo permita números de móvil
@api.onchange('Telefono2_Paciente') # if these fields are changed, call method , 'Titular_Telefono2','Telefono2'
def solonumero(self):
if not self.field1:
return {}
if not self.field1.isdigit():
raise osv.except_osv(_('Caraceter invalido'), _('Por favor, introduzca solo números'))
return {}
Aquí el código XML de la vista:
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<!-- window estetica -->
<record model="ir.ui.view" id="ingreso_form_view">
<field name="name">ingreso.form</field>
<field name="model">admision.ingreso</field>
<field name="arch" type="xml">
<form string="ingreso Form">
<sheet>
<!-- Grupo global-->
<group>
<!-- Grupos a dos columnas-->
<group>
<!-- Sub Grupos Uno-->
<field name="Nombre" placeholder = "José"/>
<field name="Apellidos" placeholder = "García García"/>
<field name="Nif" placeholder = "00000000A"/>
<field name="Fecha_Nacimiento" placeholder = "24/09/1981"/>
<field name="Direccion_Paciente" placeholder = "Olmo 22 1º" />
<field name="Poblacion_Paciente" placeholder = "Alicante"/>
<field name="Provincia_Paciente" placeholder = "Alacant"/>
<field name="CP_Paciente" placeholder = "00000"/>
</group>
<group>
<!-- Sub Grupos Uno-->
<field name="Telefono1_Paciente" placeholder = "000000000"/>
<field name="Telefono2_Paciente" on_change="solonumero(Telefono2_Paciente)" placeholder = "666666666"/>
<field name="Email2_Paciente" placeholder = "paci...@email.com"/>
<field name="Paciente_Activo"/>
<field name="Capacitado_Legalmente"/>
<field name="Fecha_Contacto"/>
<field name="Fecha_Actualizacion"/>
</group>
</group>
<!-- Aquí extensión del modulo en base a la tabla desarrollada-->
<group>
<!-- Aqui la libreta con secciones -->
<notebook>
<!-- Campos que describen globalmente la situacion -->
<page string="Seccion uno" name="Campos descriptivos">
<group>
<group>
<field name="Tipo_Lesion" placeholder = "La descripción del caso..."/>
</group>
<group>
<field name="Conocenos" placeholder = "Aporte información aquí."/>
</group>
</group>
</page>
<!-- Datos referentes al tutor de turno -->
<page string="Seccion dos" name="Datos tutor">
<group>
<group>
<field name="Nombre_Tutor_Legal" placeholder = "Adán"/>
<field name="Apellido_Tutor_Legal" placeholder = "García García"/>
<field name="Nif_Tutor_Legal" placeholder = "00000000A"/>
<field name="Direccion" placeholder = "Olmo 22 1º"/>
<field name="Poblacion" placeholder = "Alicante"/>
<field name="Provincia" placeholder = "Alacant"/>
</group>
<group>
<field name="CP" placeholder = "00000"/>
<field name="Titular_Telefono1" placeholder = "000000000"/>
<field name="Titular_Telefono2" placeholder = "000000000"/>
<field name="Titular_Email1" placeholder = "tu...@email.com"/>
<field name="Titular_Email2" placeholder = "tut...@email.com"/>
</group>
</group>
</page>
<!-- Datos referentes a los miembros principales de la unidad familiar a cargo del paciente -->
<page string="Seccion tres" name="Datos familiares">
<group>
<field name="Nif_Padre" placeholder="00000000A"/>
<field name="Nif_Madre" placeholder="00000000A" />
<field name="Mail1" placeholder = "pa...@email.com"/>
<field name="Mail2" placeholder = "ma...@email.com"/>
<field name="Telefono1" placeholder = "000000000"/>
<field name="Telefono2" placeholder = "000000000"/>
</group>
</page>
</notebook>
</group>
<group>
<button name="Guardar" string="Guardar" class="oe_right"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- override the automatically generated list view for patients -->
<!--Aqui va la vista arbol con las columnas nombre, apellido y movil-->
<record model="ir.ui.view" id="ingreso_tree_view">
<field name="name">ingreso.tree</field>
<field name="model">admision.ingreso</field>
<field name="arch" type="xml">
<tree string="ingreso Tree">
<field name="id"/>
<field name="Nombre"/>
<field name="Apellidos"/>
<field name="Telefono2_Paciente"/>
</tree>
</field>
</record>
<!-- window action -->
<!--
The following tag is an action definition for a "window action",
that is an action opening a view or a set of views
-->
<record model="ir.actions.act_window" id="ingreso_list_action">
<field name="name"> Módulo de Ingreso de Pacientes</field>
<field name="res_model">admision.ingreso</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Crea primer ingreso
</p>
</field>
</record>
<!-- top level menu: no parent -->
<menuitem id="main_admision_menu" name="Admisiones"/>
<!-- A first level in the left side menu is needed
before using action= attribute -->
<menuitem id="admision_menu" name="Admisiones"
parent="main_admision_menu"/>
<!-- the following menuitem should appear *after*
its parent openacademy_menu and *after* its
action course_list_action -->
<menuitem id="ingreso_menu" name="Ingreso" parent="admision_menu"
action="ingreso_list_action"/>
<!-- Full id location:action="admision.ingreso_list_action"
It is not required when it is the same module -->
</data>
</openerp>
Aquí el típo de error que arroja al intentar ejecutar el formulario:
Odoo Server Error
Traceback (most recent call last):
File "/opt/odoo/odoo-server/openerp/http.py", line 544, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/opt/odoo/odoo-server/openerp/http.py", line 581, in dispatch
result = self._call_function(**self.params)
File "/opt/odoo/odoo-server/openerp/http.py", line 317, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/opt/odoo/odoo-server/openerp/service/model.py", line 118, in wrapper
return f(dbname, *args, **kwargs)
File "/opt/odoo/odoo-server/openerp/http.py", line 314, in checked_call
return self.endpoint(*a, **kw)
File "/opt/odoo/odoo-server/openerp/http.py", line 810, in __call__
return self.method(*args, **kw)
File "/opt/odoo/odoo-server/openerp/http.py", line 410, in response_wrap
response = f(*args, **kw)
File "/opt/odoo/odoo-server/addons/web/controllers/main.py", line 944, in call_kw
return self._call_kw(model, method, args, kwargs)
File "/opt/odoo/odoo-server/addons/web/controllers/main.py", line 936, in _call_kw
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
File "/opt/odoo/odoo-server/openerp/api.py", line 268, in wrapper
return old_api(self, *args, **kwargs)
File "/opt/odoo/odoo-server/openerp/api.py", line 399, in old_api
result = method(recs, *args, **kwargs)
File "/opt/odoo/odoo-server/openerp/models.py", line 5985, in onchange
record._onchange_eval(name, field_onchange[name], result)
File "/opt/odoo/odoo-server/openerp/models.py", line 5875, in _onchange_eval
method_res = getattr(self._model, method)(*args, context=self._context)
AttributeError: 'admision.ingreso' object has no attribute 'solonumero'
Aquí el codigo que agrege para el intento de crear ese mecanismo (esto es; que enseñe un aviso diciendo
que no puedes meter meter otra cosa que no sean numeros y que metas numeros.)
<field name="Telefono2_Paciente" on_change="solonumero(Telefono2_Paciente)" placeholder = "666666666" />
AAquí el scrip de python:
# aquí viene decorador función para que solo permita números de móvil
@api.onchange('Telefono2_Paciente') # if these fields are changed, call method , 'Titular_Telefono2','Telefono2'
def solonumero(self):
if not self.field1:
return {}
if not self.field1.isdigit():
raise osv.except_osv(_('Caraceter invalido'), _('Por favor, introduzca solo números'))
return {}
He mirado en la documentación oficial, foros y webs en castellano e ingles, recurro aquí por ser ultima opción,
disculpen las molestias y gracias por su atención y ayuda.
Un saludo,
Marco García Baturan.