47526968 Creacion Del Primer Modulo

Creación de un módulo OpenERP

Índice de contenidos
1. Introducción......................................................................................................................................3 2. Modelo, Vista, Controlador (MVC)..................................................................................................4 2.1. Modelo Vista Controlador en OpenERP...................................................................................5 3. Los módulos.....................................................................................................................................6 3.1. Módulo ejemplo academy.........................................................................................................6 4. Descripción de módulo: Fichero __openerp__.py............................................................................8 4.1. Módulo ejemplo academy.........................................................................................................8 5. Programación del modelo en Python..............................................................................................10 5.1. Definición de las tablas...........................................................................................................10 5.1.1. Definición de las columnas..............................................................................................10 a) Campos simples................................................................................................................10 b) Campos relacionales.........................................................................................................11 c) Campos funcionales.........................................................................................................12 5.1.2. Módulo ejemplo academy................................................................................................12 6. Programación de los menús, acciones y vistas: Archivos XML.....................................................15 6.1. Los menús................................................................................................................................16 6.1.1. Módulo ejemplo academy................................................................................................17 6.2. Las acciones............................................................................................................................18 6.2.1. Acciones window (apertura de vistas).............................................................................18 6.2.2. El dominio de la acción. Condiciones.............................................................................21 6.2.3. Módulo ejemplo academy...............................................................................................22 6.3. Las vistas.................................................................................................................................23 6.3.1. Vistas de formulario........................................................................................................25 a) Módulo ejemplo academy................................................................................................28 6.3.2. Vistas de lista o árbol......................................................................................................31 a) Módulo ejemplo academy.................................................................................................31 7. Anexo 1...........................................................................................................................................34

1.  Introducción
OpenERP  es un programa Cliente/Servidor basado en Python para la planificación de recursos  empresariales   (ERP).   Consta   de   un   cliente  OpenERP­Client  y   un   servidor  OpenERP­Server  mientras   que   la   persistencia   de   datos   está   proporcionada   por   la   base   de   datos   relacional  PostgreSQL.

Figura 1.1: Estructura de OpenERP  OpenERP utiliza el protocolo XML­RPC o NET­RPC para la comunicación entre cliente y servidor  También dispone de un cliente web para generar la interfaz gráfica del usuario como una página  web y así poder usar OpenERP desde un navegador web (figura 1.1). Una vez instalado, OpenERP tiene una estructura modular permitiendo añadir módulos según vaya  siendo necesario. OpenERP   funciona   sobre   un   entorno   de   desarrollo   o   framework   llamado   OpenObject.   Este  framework permite el desarrollo rápido de aplicaciones (RAD ­ Rapid Application development) OpenObject es un entorno de desarrollo rápido de aplicaciones de gestión orientado a objetos en  Python usando base de datos PostgreSQL. Sus componentes son:
● ● ● ● ● ●

ORM (Object Relational Mapping): Mapeo de bases de datos relacionales a objetos Python Arquitectura MVC (Modelo Vista Controlador) Sistema de flujos de trabajo o workflows Diseñador de informes o reports (OpenOffice, JasperReports, ...) Herramientas BI (Business Intelligence) y OLAP cube engine Clientes Gtk, Koo (KDE) y Web

En aplicaciones complejas que presentan multitud de datos para el usuario.1: Modelo Vista Controlador.  El  modelo­vista­controlador  resuelve este  problema  mediante  la  disociación del acceso a datos y la lógica de negocio de la presentación de los datos y la interacción  del usuario.1). las flechas continuas que van desde el controlador a la vista y  al modelo significan que el controlador tiene acceso completo tanto a la vista como al modelo. Controlador (MVC) OpenERP utiliza el patrón de arquitectura de software Modelo Vista Controlador (figura 2. El controlador es el responsable de recibir los eventos de entrada desde la vista. Las  flechas discontinuas que van desde la vista hacia  el controlador  significan que la vista tiene un  acceso limitado al controlador. Vista. Por ejemplo. a menudo es deseable  separar los datos (modelo) y la interfaz de usuario (vista). de manera que los cambios en la interfaz  de usuario no afectan a la manipulación de datos.2. Una definición de este patrón podría ser la que ofrece Wikipedia: Modelo Vista Controlador (MVC)  es un patrón de arquitectura de software que separa en tres componentes distintos: ● ● ● Los datos de la aplicación (modelo) La interfaz de usuario (vista) La lógica de control (controlador) El patrón MVC se ve frecuentemente en aplicaciones web donde: ● ● ● La vista es la página HTML y el código que provee de datos dinámicos a la página. en el diagrama anterior. mediante la introducción de un componente intermedio: el controlador. Figura 2. y que los datos pueden ser reorganizados sin  cambiar  la  interfaz  de usuario.  Modelo. Las razones de este diseño son las siguientes: . El modelo es el Sistema de Gestión de Base de Datos y la lógica de negocio.

 . con el fin de que la vista pueda actualizar su contenido. . El modelo no necesita  conocer el funcionamiento interno de la vista para realizar esta operación. definidas en archivos XML. la vista  necesita acceso a la partes internas del controlador. . .1. formularios. calendarios. cálculos... gráficos. informes.  Modelo Vista Controlador en OpenERP En OpenERP. • Vista (view): Listas. • Controlador  (controller): Métodos Python definidos dentro de los objetos de OpenERP que  proporcionan la lógica: Validación de datos. acciones. asistentes. Permite la creación/actualización automática de las tablas  y acceder a las tablas sin usar SQL. Sin embargo.. En estos  archivos también se definen menús.. 2.• Acceso de modelo a vista: El modelo envía la notificación a la vista cuando sus datos han sido  modificados. • Acceso de  vista a  controlador: Las dependencias que la vista tiene sobre el controlador deben  ser mínimas ya que el controlador pueda ser sustituido en cualquier momento.. podemos aplicar este modelo­vista­controlador de la siguiente manera: • Modelo (model): Los objetos de OpenERP con sus columnas que normalmente se guardan en las  tablas de PostgresSQL con sus campos..

 Estos archivos deben ser indicados dentro del archivo __openerp__.  Los módulos El uso de los módulos es la manera de ampliar la funcionalidad OpenERP. ). • Opcionalmente.   crear   informes/listados. aunque recomendable..3. res. wizard. menús. • crm: Gestión de la relación con los clientes/proveedores.. monedas.partner.0 se denominaba __terp__. res.currency.   esto   se   puede   copiar   de   cualquier   fichero   de  cualquier módulo y adaptarlo a nuestras necesidades. • sale: Gestión de ventas. usuarios. Una instalación de  OpenERP  se compone de un núcleo y de varios  módulos  dependiendo de las  necesidades. • Crear un archivo con la descripción del módulo de OpenERP: __openerp__. tarifas.company. Los pasos básicos para generar un módulo son: • Crear un subdirectorio dentro de la carpeta bin/addons del directorio de instalación del servidor  OpenERP.. por  ejemplo: • base: El módulo básico compuesto por los objetos básicos como compañías..  • product: Gestión de productos. Todos   los   módulos   están   ubicados   en   la   carpeta  bin/addons  del   directorio   de   instalación   del  servidor OpenERP.py (que importa los otros archivos .partner.user. . datos de ejemplo. .py (Nota: Hasta la  versión 5.py . .py).  Módulo ejemplo academy La carpeta de nuestro módulo academy tendrá una estructura similar a esta: • academy – __openerp__. direcciones. Aquí es  donde se define el modelo y el controlador.  empresas.1. • purchase: Gestión de compras.   Pueden   estar   en  subcarpetas (report. acciones.py – __init__.  Los nuevos módulos pueden programarse fácilmente y requieren un poco de práctica en XML y  Python. (res...py. 3. ). Este módulo se instala siempre.) • Opcionalmente. res. almacenes.   asistentes   y   flujos   de   trabajo..  • Crear los archivos XML para la definición de datos (vistas. • mrp: Fabricación y planificación de recursos. En todos los ficheros acostumbra a aparecer una cabecera que es un comentario Python referido a la  licencia   del   módulo   y   el   copyright   del   autor/es. poner las traducciones en una carpeta llamada i18n i las  reglas de seguridad en una carpeta llamada security dentro del mismo módulo. • stock: Gestión de logística.address. • Crear los archivos Python que contendrán los objetos (clases con atributos y métodos). res.py  que tenga el módulo)..  • Crear un archivo de inicio del módulo de Python: __init__.  • account: Gestión contable / financiera / analítica. .

– – – – academy.po ∙ ca.access.pot ∙ es. tenemos que incluir la siguiente línea en el archivo __init__.py: import academy .po Si dentro de nuestro módulo academy creamos un archivo "academy.xml security ∙ ir.py" que contiene la definición  de nuestros objetos.csv i18n ∙ academy.py academy_view.model.

 licencia. que debe tener  formato de un diccionario de Python.1". demo_xml: Lista de archivos XML que se cargaran si se ha instalado el servidor OpenERP con  datos de demostración o ejemplo. Muchas veces se incluye el módulo  base en las dependencias ya que algunos datos de este módulo son necesarios para las vistas. categoría.   Texto   separado   por   barras   /   con   la   ruta  jerárquica de las categorías. update_xml:  Lista de archivos XML que se cargaran al iniciar el servidor OpenERP con la  opción "­update=modulo". "description": """Academy module description""". "init_xml" : [ ]. descripción.py para el módulo academy: { "name" : "academy". installable: Acepta valores True o False y determina si el módulo es instalable o no. "author" : "zikzakmeida".com". entre otras cosas: • El nombre.py) ubicado en la raíz de nuestro módulo .  depends: Lista de módulos de los que depende este módulo. "update_xml" : ['academy_view.xml']. "demo_xml" : [ ].... "category" : "Generic Modules". active: acepta valores True o False y determina los si el módulo será instalado cuando se crea la  base de datos (por defecto False) • • • • • 4.0  se denominaba __tinyerp__. author: Autor del módulo website: Sitio web del modulo license: Licencia del módulo (por defecto GPL­3) category:   Categoría   a   la   que   pertenece   el   módulo. es responsable de determinar..  Descripción de módulo: Fichero __openerp__.1. "depends" : ['base']. .  informes. Las rutas de los archivos debe ser relativas al directorio donde  está el módulo. version: Versión del módulo description: Descripción del módulo. "website" : "http://zikzakmedia. "version" : "0. Este archivo. del módulo. Este archivo debe contener los siguientes valores dentro de un diccionario Python  (estructura de  datos cerrada con llaves { }): • • • • • • • • name: Nombre del módulo. versión. autores.  • Las dependencias con otros módulos. init_xml: Lista de archivos XML que se cargaran al iniciar el servidor OpenERP con la opción  "­init=modulo".py (hasta la versión 5.  Módulo ejemplo academy Este es un ejemplo del archivo __openerp__. • Los archivos XML que serán analizados durante el arranque del servidor OpenERP. Las rutas de los archivos debe ser relativas al directorio donde está  el módulo.4. . Las rutas de los archivos debe ser relativas al directorio donde está el módulo.py Cualquier módulo que creemos debe contener un un archivo __openerp__. "installable": True .

py  están dentro de un diccionario Python dentro de  llaves { }. menús.  informes y  asistentes. Observar que: • Todos los datos del archivo  __openerp__. para cargar datos en la instalación del módulo. Los archivos que se incluyen en demo_xml son para cargar los datos de demostración.  update_xml  o  demo_xml  están dentro de una  lista de Python dentro de corchetes [].} Los archivos que se deben incluir en el parámetro init_xml son los que se refieren a las definiciones  del flujo de trabajo.  acciones. . • Los archivos XML de los parámetros  init_xml. Los archivos que se incluyen en  update_xml  conciernen a vistas.

  Este   nombre   se   usará   por   defecto   como   nombre   de  la   tabla   de  PostgreSQL. Hay dos atributos obligatorios  (que siempre se deben definir) y el resto son opcionales. time: Hora. La sintaxis general para definir una columna es la siguiente: 'nombre_campo':fields.tipo_de_campo('String'. • _slq_constraints:   Se   utiliza   para   definir   restricciones   a   nivel   de   código   SQL   en   las   tablas  gestionadas por PostgreSQL.  Aunque estrictamente hablando sean  clases de Python.1. • _columns: Contiene un diccionario Python con la declaración de las columnas de la tabla. char: Cadena de caracteres. selection: Toma uno de una serie de valores predefinidos. text: Texto.  Definición de las columnas Dentro del atributo  _columns  de la clase que define la tabla.1. proporciona una serie de  campos (fields) predefinidos. 5. Existen los siguientes: a)  Campos simples • • • • • • • • • boolean: Sólo puede tomar los valores verdadero y falso (True o False). cambiando los puntos por guiones bajos. Para ello. • _constraints: Se utiliza para definir restricciones a nivel de código Python en la gestión de las  tablas a través de OpenERP.5. Entre los atributos opcionales podemos destacar: • _defaults: Sirve para determinar valores por defecto en determinadas columnas. datetime: Fecha y hora.1.  Definición de las tablas En OpenERP. Los obligatorio son: • _name: Contiene el nombre de la tabla (normalmente incluye al principio el nombre del módulo  separado   por   un   punto). date: Fecha.py vamos a definir los modelos u  objetos en OpenERP. • _inherit: Sirve para heredar de otra clase existente en OpenERP. 5. se les acostumbra a llamar objectos de OpenObject.['parametro_opcional'. float: Número real. las tablas de PostgreSQL se crean mediante una serie de atributos predefinidos  en  clases escritas en codigo Python heredadas de la clase osv. el componente de OpenObject.osv. Object Service (OSV). los cuales crearán de forma automática las tablas y campos en la base de datos  PostgreSQL. deben definirse las columnas de la  misma. integer: Número entero.]) Donde tipo_de_campo es el tipo de campo de la tabla relacional PostgreSQL.. .. • _table: Nombre de la tabla SQL si queremos que sea distinto de _name (se sustituye los puntos  por guiones bajos)..  Programación del modelo en Python Después de describir el módulo mediante el fichero __openerp__.

. Todos estos campos tienen una serie de atributos comunes que se pasan como parámetros de la  función y entre los que cabe destacar: 'string'. • size: que es el máximo número de caracteres para los campos de tipo char..'String'. 'field_id'. 'Field Name'. las relaciones “permiten establecer interconexiones (relaciones) entre los datos  (que están guardados en tablas). 'other..object. Es la  relación contraria y/o complementaria a many2one. Se pueden dar tres tipos distintos de relaciones entre los objetos de OpenERP que se pueden  plasmar mediante tres tipos diferentes de campos: • many2one: Un campo many2one expresa una relación hacia un objeto padre (de muchos a uno). Por  defecto es 0. • digits: proporciona la precisión y la escala que se el desea asignar mediante una tupla en los  campos de tipo float. ..('key2'. Común a  todos los tipos... • many2many: Un campo many2many representa una relación de muchos a muchos entre dos  objetos.. Además. algunos tipos de campo tienen atributos específicos: • translate: que es True si el valor del campo puede ser traducido por los usuarios.'other_object_field_id'. 'Field Name'. • binary: Campo para almacenar un archivo o contenido binario.'field_id'. • values: campo que permite seleccionar entre un conjunto de valores predefinidos en los campos  de tipo selection. Donde: • other.. • required: Si el campo es obligatorio. • help: Mensaje de ayuda (el que aparece en el interrogante verde al lado de la etiqueta del campo).. True..object.name'.'relationship_table'. . b)  Campos relacionales Según la wikipedia. Este atributo se coloca antes que el atributo string.• reference: Campo con una relación dinámica hacia otro objeto de OpenERP seleccionable dentro  de una lista de posibles objetos (se puede editar desde el menú Administración/Objetos de bajo   nivel/Solicitudes/Enlaces acceptados en solicitudes)..object. Por defecto es False. poner a  1  (búsqueda simple). • readonly: Si el campo es de sólo lectura.]. True.'Labe2'). y se define mediante una  lista de valores o una función que devuelve una lista de valores... Para búsqueda avanzada poner a  2. y a través de dichas conexiones relacionar los datos de ambas  tablas”. La lista debe estar compuesta por  tuplas que contienen una clave y su etiqueta. [('key1'.object. Disponible para  los campos char y text. • one2many: Un campo one2many expresa una relación de un objeto hacia muchos objetos. . Por defecto es False.  usando una llave foránea (foreing key). Obligatorio.['parametro_opcional'. Este atributo es el único  obligatorio. 'other.name'.] • string: Es una cadena de texto que pone nombre a la etiqueta del campo.'Label1'). • select: Si se quiere que de dicho campo se genere un índice (de PostgreSQL) para optimizar las  búsquedas de las vistas.name'...name: Es el nombre del objeto de destino (con el que guarda relación).. 'other.

'address_ids': fields.many2one('res.address'. Obligatorio. sabe a que tipo de  campo se refiere.integer('Capacity'.  • property:   Campos   dinámicos   con   derechos   de   acceso   específicos. help='State of the classroom').py  que   permita   gestionar   las   aulas   de   la  academia se introduce el siguiente código: class academy_classroom(osv.osv): """Academy Classrooms""" _name = 'academy.• Field Name: es el nombre del campo.'Usable'). . help='Capacity of the classroom').selection([('usable'. Para   crear   el   objeto  classroom  del   módulo  academy. Común a los tipos one2many  y many2many. 5. – readonly: True por defecto. Valor predefinido: cascade. Por ejemplo.2.partner. Los valores de los campos de tipo property se pueden  consultar en el menú Administración/Configuración/Propiedades. • other_object_field_id: es el campo identificador de la relación de la otra tabla. 'capacity': fields. Según la compañía a la que pertenezca  el usuario. Así el programador.'Address'. Solo para el tipo  many2many.   los   campos  Cuenta a cobrar y Cuenta a pagar de la ficha de empresa.   para  aumentar la velocidad de consulta de OpenERP y facilitar las búsquedas.boolean('Active'). con sólo verlos.1.   En   casos   especiales. – select: True ­ (crea un índice en el campo de la clave foránea) • optionalParameters: para el tipo one2many. el campo Ciudad de las Empresas es un campo  relacionado pues en realidad se usa el campo Ciudad de las Direcciones/Contactos de la empresa.  Módulo ejemplo academy. Pueden ser: – invisible: True/False – readonly: True/False Por convenio los nombres de los campos many2one terminan en _id y los nombre de los campos  one2many y many2many terminan en _ids.size=35.   Por   ejemplo. • related: Permite visualizar un campo de un objeto relacionado en el propio objeto. • optionalParameters: para el tipo many2one. los campos funcionales  también pueden ser guardados en la base de datos aunque siempre son calculados/actualizados  por una o varias funciones y no por los usuarios.'In Works') ]. • field_id: es el campo identificador de la relación de la propia tabla. elimina los recursos dependientes Valor por defecto: null.char('Classroom'. c)  Campos funcionales • function: Los campos funcionales simulan campos reales. Común y obligatorio en todos los tipos de campos. help='Name of the classroom'). 'active': fields. pero se calculan mediante una función  Python   en  lugar  de   almacenarse   en  las   base   de  datos   PosgreSQL. no elimina los recursos sino que los establece a un valor nulo. el valor de estos campos varía. Pueden ser: – ondelete: Indica qué debería ocurrir cuando el recurso al que este campo señala es eliminado. help='Address of the classroom'). Obligatorio. • relationship_table: es la tabla que establece la relación en las relaciones de tipo  many2many.classroom' _columns = { 'name': fields. Equivalente a  navegar por campos encadenados. – required: True por defecto. 'state': fields.('in works'.'State'.  Obligatorio.

'category_id': fields.many2one('academy. } academy_course() Observar que en este diseño del módulo  academy  se ha supuesto que un curso se imparte en una  aula y pertenece a una categoría.float('Studies Hours'.'Parent Category'. help='Dificulty of the course').  Permite guardar la dirección física donde se ubica la aula.char('Category'.category' _columns = { 'name': fields.address en una relación varios a uno (many2one). } _defaults = { 'state': lambda *a: 'draft'.'Dificulty'.'Stable')]. se puede comprobar que los valores por defecto de los campos  state y active.many2one('academy. help='Name of the parent category'). help='Category of the course').course.classroom'. 'description': fields. 'dificulty': lambda *a: 'low'. ('high'.('testing'.course' _columns = { 'name': fields. 'classroom_id': fields.size=16.category'. 'dificulty': fields.'Medium').category'. help='Class in which the course is taught').selection([('draft'.'Classroom'. } academy_classroom() Con este código se creará una tabla de PostgreSQL que utilizará el nombre academy_classroom.partner. 'active': lambda *a: 1. ('stable'. 'parent_id': fields. Determina si el campo es visible “True” o no “False”.osv): """Courses taught by academy""" _name = 'academy. En este ejemplo.char('Course'. Esto se consigue con el  atributo _defaults. Los modelos/tablas course y course_category para gestionar cursos y categorías de cursos se crean  de forma análoga. help='Hours of the course').many2one('academy.course. 'state': fields.osv): """Courses Categories""" _name = 'academy.} _defaults = { 'state': lambda *a: 'usable'. Algunos campos  necesitan que se modifiquen sus valores por defecto. 'hours': fields. help='Description of the course'). Modelo curso: class academy_course(osv.course. Modelo categoría de cursos: class academy_course_category(osv. • address_id: Un enlace con la clase res.text('Description'.size=32.selection([('low'.'State'). help='Name of the category').'Category'. • active: Un campo booleano.  con los siguientes campos: • name: Un campo que contiene una cadena de caracteres con el nombre de la aula. .'Low').'High')].('medium'. se han establecido a los valores por defecto usable y 1 (True) respectivamente.'Draft'). • state: Un campo de selección con el estado en que se encuentra la aula. • capacity: Un campo que contiene un número entero con la capacidad de la aula. help='Name of the course').'Testing').

.} academy_course_category() Observar que el campo parent_id es un campo many2one que se apunta a si mismo y permite crear  una   estructura   jerárquica   de   categorías.   donde   cada   categoría   apunta   a   su   padre   excepto   las  categorías principales.

 Por  ejemplo.xml.xml Pero para acceder a dichas vistas. ¿cómo se muestran dichos  objetos al usuario? Primero de todo. sería: academy_view. Una  vez modificada la vista. el formulario para modificar los datos de una empresa no es el mismo que el utilizado para  modificar una factura.object_xml_id')"/> </record> </data> </openerp> Las vistas describen como se muestra cada objeto (tipo de recurso). En adelante.   calendarios. Precisando más.   gráficos. nótese que cada tipo de recurso utiliza su propia interfaz.  Programación de los menús. acciones y vistas para poder interactuar con el objeto. Por lo tanto. sino que son construidas de  forma dinámica por la descripción XML de la pantalla del cliente. debe tenerse en cuenta que las interfaces son dinámicas.   formularios. una vez creado el primer objeto para el módulo. se llamará a estas  pantallas   de   descripción   vistas   (listas.object_xml_id"/> <field name="field2" eval="ref('module.).0" encoding="utf-8"?> <openerp> <data> <record model="object_model_name" id="object_xml_id"> <field name="field1">value1</field> <field name="field2">value2</field> </record> <record model="object_model_name2" id="object_xml_id2"> <field name="field1" ref="module.6. deben definirse previamente los menús. simplemente se necesita cerrar la pestaña correspondiente a dicha vista y  reabrirla para que aparezcan los cambios. acciones y vistas: Archivos XML Dado que todos los datos del programa están almacenados en objetos.  Esto significa que no se describen de forma estática por un código. lo siguiente que se debe hacer es crear  el fichero encargado de crear los menús. y cómo  debe hacerse. para cada  objeto. así como las acciones  . se pueden definir una o varias vistas que describen qué campos deben mostrarse.   . En consecuencia.  Una  característica  notable de dichas vistas es que pueden editarse en cualquier momento (incluso durante la ejecución  del programa) desde el menú Administración / Personalización / Interfaz de usuario / Vistas... Hay varios tipos de vistas: • • • • • • • Formulario Lista Árbol Gráfico Calendario Diagramas de Gantt Búsqueda Para crear las vistas del módulo se debe crear/editar el fichero nombre_modulo_view. La  estructura general del dicho fichero es la siguiente: <?xml version="1. En el  presente ejemplo.

asociadas a los mismos.. . los  iconos “Proyectos”. “Recursos Humanos”. Esta es la plantilla para crear un menú: <menuitem id="menuitem_id" name="Position/Of/The/Menu/Item/In/The/Tree" action="action_id" icon="NAME_FROM_LIST" parent="menuitem_id" groups="groupname" sequence="<integer>" /> Donde: • menuitem_id: Especifica el identificador del menú en la tabla interna de OpenERP donde se  guardan los menús.   En   el   apéndice   1   se   muestran   los   iconos   disponibles.actions. que se instala por defecto en  todos los servidores OpenERP. Este campo es obligatorio. • parent: Especifica el identificador del menú padre del que depende.  • icon: Especifica qué icono se mostrará para el menú. . 6.  Los menús.   Esto   es   útil   para  personalizar iconos de menú que deben actuar como árboles de directorios (por ejemplo. Nótese que este campo no es obligatorio: se puede definir elementos de  menú sin asociarles acción alguna. • name: Define el nombre del menú en la jerarquía de menús. el menú tomará el nombre de la acción asociada. se han definido de esta forma). • action: Especifica el identificador de la acción que debe haber sido definida en la tabla de acción  (ir. Figura 6. Este campo es opcional. El icono por defecto es el de una carpeta  (STOCK_OPEN).act_window).1.1 muestra un ejemplo de los menús del módulo empresa. La figura 6.1: Ejemplo de menús.. si no se  indica. Este identificador debe ser único.

• sequence: es un entero que se usa para ordenar el menú dentro del árbol de menús.  Módulo ejemplo academy Estas podrían ser las líneas (dentro del fichero academy_view. Si  se   desea   introducir   más   de   un   grupo. Los menús  que tengan el mismo valor de sequence se ordenan por orden de creación. 6. Figura 6.1. Cuanto más  grande sea el número de sequence.   se   deben   separar   mediante   comas   “.”   (por   ejemplo:  groups=”admin.2) que ejecutarán 3 acciones distintas.  Classroom  y  Courses Categories (figura 6.1. más abajo aparecerá en el árbol de menús. el menú toma el valor por defecto: 10. Este argumento no  es obligatorio: si no se especifica  sequence.py: <menuitem name="Academy" id="menu_academy"/> <menuitem name="Courses" id="menu_academy_course" action="action_academy_course" parent="menu_academy"/> <menuitem name="Classroom" id="menu_academy_classroom" action="action_academy_classroom" parent="menu_academy"/> <menuitem name="Courses Categories" id="menu_academy_course_category" action="action_academy_course_category" parent="menu_academy"/> Como se puede ver. hay un menú principal (no tiene padre) denominado Academy que se muestra en  la barra de menús de OpenERP y tres menús que dependen del primero:  Courses.user”).xml) que definiesen los menús del  módulo academy.2: Menú Academy .• groups: Especifica qué grupo de usuarios puede ver el menú (por ejemplo: groups=”admin”).

1. se recomienda seleccionar un menú concreto (por  ejemplo el menú Empresas / Empresas / Empresas por categorías). Las acciones window son las más habituales.3. 6. La tabla 1 muestra qué modos de vista pueden abrir cada  tipo de vista. • report: Imprime un informe. y cambiar el modo de vista (en  este caso a modo de formulario) pulsando Ctrl + L. Las vistas”. • El clic en algún botón de una vista que esté asociado a una acción. las más importantes: • window: Abre una vista en una nueva ventana/pestaña.acciones.2.acc_ventena)  permiten abrir diferentes tipos y modos de vistas (en el apartado “6.3.6. Hay diferentes tipos de acciones.  Acciones window (apertura de vistas) Las acciones window (denominadas internamente ir. El resultado es el mostrado en la figura 6. aunque también pueden ser report o wizard). • Los clics de ratón del usuario sobre el icono “imprimir” (se ejecuta una acción report) o “acción”  (se ejecuta una acción wizard). Tipos de vista ● Modos de vista permitidos ● ● ● ● ● Tree (Árbol) tree (árbol) form (formulario) tree (lista) form (formulario) graph (gráfico) gantt (diagrama de gantt) calendar (calendario) search (búsqueda) inheritance (herencia) ● Form (Formulario) ● ● ● ● Tabla1: Tipos de vista y modos de vista permitidos Para ver ejemplos de acciones asociadas a menús.act_window o ir.  Las acciones Las acciones definen el comportamiento del sistema en respuesta a los eventos generado por el  usuario. Las acciones se utilizan para capturar los siguientes eventos en el cliente: • Los dobles clics del ratón del usuario sobre un menú (normalmente se ejecutan acciones del tipo  window. se describirán las  diferencias entre tipos y modos de vistas). .actions.2. • wizard: Ejecuta un asistente para realizar un determinado trabajo o proceso.

 lo que indica que   . Como puede comprobarse.acc_ventana. la acción “Proveedores” (figura 6. es decir las vistas árbol y formulario.4). En el  campo  Acción  este menú está relacionado con una acción  ir.Figura 6. como icono el  STOCK_INDENT  y no se ha asociado ningún grupo de usuarios.  abre una vista de tipo “Formulario” y permite los modos de vista “tree” y “form”. se accede a la ventana que describe dicha acción  (figura 6. Haciendo clic  sobre el icono de la carpeta del campo  Acción. En cambio.4: Acción asociada al menú “Empresas por categorías” que  abre una vista de tipo árbol. y  permite los modos de vista “tree” y “form”.5) asociada al menú Empresas/Empresas/Proveedores. el tipo de vista para la acción “Empresas por categorías” es “Árbol”.acciones. Observamos   que   este   menú   denominado  Empresas   por   categoría  tiene   como   padre   el   menú  Empresas.3: Vista en modo formulario del menú “Empresas por categorías”. Figura 6.

por defecto abre la vista en modo lista y se puede cambiar más tarde a formulario. Figura 6.6: Acción asociada al menú “Nueva empresa”.6) también es de tipo  formulario pero a diferencia de la anterior. Por este motivo al hacer clic este menú nos aparecerá el  formulario de empresas en blanco. abre por defecto la vista en modo formulario y permite  más tarde cambiar a la vista en modo lista. Este es un ejemplo genérico de una acción de ventana guardado en el fichero XML: <record model="ir.1)]  que es la condición para hacer el  filtrado de las empresas que sean proveedores (lista de Python con condiciones).act_window" id="action_id_1"> <field name="name">action.5: Acción asociada al menú “Proveedores” que  abre una vista de tipo formulario.name</field> .actions. Observar como  esta acción tienen como valor de dominio  [('supplier'. La acción asociada al menú  Empresas/Empresas/Nueva empresa  (figura  6.'='. Figura 6.

 Los diccionarios contextuales se declaran como un diccionario Python. Este parámetro permite regular qué recursos serán visibles en la vista seleccionada (condición). almacén. Estos diccionarios  contienen información de contexto como por ejemplo el idioma.). En esta caso siempre será “ir. • El valor de la condición.'valor'). Un registro  de la tabla sólo se mostrará en la vista si satisface todas las condiciones. form.form:   La   vista   se   muestra   primero   en   modo   lista. res_model: Es el nombre del objeto sobre el que opera la acción.. . moneda. >.tree: La vista se muestra primero en modo formulario. a  usar.. Las condiciones de la lista se enlazan  con una cláusula AND y son tuplas Python con 3 valores ('campo'.2. se utilizaría el primer tipo de vista  definido). name: Es el nombre de la acción (obligatorio). en el caso de facturas. like). view_mode: Sólo se tiene en cuenta si “view_type” se ha establecido a “form”. Las cuatro posibilidades  más habituales son: – form. se puede definir una acción que abra una vista que muestre sólo  facturas borrador. graph. Debe ser único.. – tree: La vista se muestra como una lista y no hay forma de cambiar al modo formulario.2. domain: Es una lista Python de condiciones utilizada para refinar los resultados de una selección. pero se puede mostrar en modo  lista clicando el botón Lista.  El dominio de la acción. Si este campo no se  definiese. • • • 6.  . en cualquier otro  caso. view_type: Se debe establecer a “form” para que la acción abra una vista de tipo formulario.. . y a  “tree” cuando la acción deba abrir una vista de tipo árbol. – form: La vista se muestra como un formulario y no hay forma de cambiar al modo lista. Lista de vistas a usar (tree. Los dominios se escriben en Python: Lista de tuplas. view_id: Es el nombre de la vista a mostrar cuando se activa la acción. se ignora. para mostrar menos registros en la vista. cada una de las cuales tiene tres elementos: • El campo en el que se debe realizar la condición.actions. calendar. tarifa.<field <field <field <field <field <field <field <field </record> name="view_id" ref="view_id_1"/> name="domain">["list of 3-tuples (max 250 characters)"]</field> name="context">{"context dictionary (max 250 characters)"}</field> name="res_model">Open.  y en consecuencia. id: Es el identificador de la acción. Por  ejemplo.object</field> name="view_type">form|tree</field> name="view_mode">form. – tree.form|form|tree</field> name="usage">menu</field> name="target">new</field> Donde: • • • • • • model: Es el nombre del objeto que creamos. se usaría el tipo de vista (lista o formulario) asociado al objeto res_model con el campo  de mayor prioridad (si dos vistas tuviesen la misma prioridad. Condiciones. • El operador utilizado para la condición (<.'condición'. =.   pero   se   puede   mostrar   en   modo  formulario clicando el botón Formulario.act_window”.tree|tree. context: Es el diccionario contextual que se utilizará en la vista que se abra cuando se active la  acción.

  Módulo ejemplo academy El siguiente código muestra las acciones del módulo academy.'draft')].actions.form</field> </record> <record model="ir. cada acción opera (res_model) sobre un modelo distinto  del módulo academy. .  cada una tiene un identificador id único.form (lista  y   formulario).category</field> <field name="view_type">form</field> <field name="view_mode">tree. Las 3 acciones son de tipo form y permiten los modos de vista tree.form</field> </record> Como se puede comprobar.actions.form</field> </record> <record model="ir.act_window" id="action_academy_course_category"> <field name="name">Courses Categories</field> <field name="res_model">academy.3.act_window" id="action_academy_classroom"> <field name="name">Classroom</field> <field name="res_model">academy. 6.'='.actions.actions.act_window" id="action_academy_course"> <field name="name">Courses</field> <field name="res_model">academy. <record model="ir. se usaría el siguiente dominio:  [('state'.classroom</field> <field name="view_type">form</field> <field name="view_mode">tree. si se desea obtener solo facturas en estado “Borrador”.Por ejemplo.course</field> <field name="view_type">form</field> <field name="view_mode">tree.course.2. todas las acciones se almacenan en el modelo “ir.   No   tienen   definido   ningún  dominio   (por  lo   que   se  verán   todos   los   registros)  ni  tampoco se ha forzado a usar ninguna vista en concreto (se usarán las vista por defecto que veremos  en el siguiente apartado).act_window”.

Existen dos tipos de vistas distintos: tipo  Árbol  y tipo  Formulario. .7 puede  verse como.. Desde el menú del recuadro azul (“Empresas por categorías”) se accedería a una vista de tipo árbol  con una organización interna jerárquica (figura 6.6. puede accederse directamente a distintos tipos de  vistas. gráfico. calendario.. Figura 6.7: Menús cuyas acciones abren distintos tipos de vistas. El tipo de vista  Formulario  permite a su vez una serie de modos: lista. desde el menú Empresas/Empresas. formulario.  Las vistas. .8). En la figura 6.3.

8: Vista de tipo árbol.Figura 6. se accedería directamente a una  vista de formulario (figura 6.9: Vista en modo lista. Figura 6. . Finalmente. Desde el menú del recuadro rojo (“Proveedores”) se accedería a una vista de tipo lista (figura 6.9).10). desde el menú del recuadro verde (“Nueva empresa”).

view" id="view_id"> <field name="name">view..Figura 6. .search. <graph>.  Vistas de formulario La disposición de los campos en una vista de formulario siempre sigue el mismo principio: Los  campos se distribuyen en la pantalla siguiendo las siguientes reglas: • Por defecto.. 6. de acuerdo al  orden con el que están declarados en la vista.). • model:  Modelo  u objeto sobre el  que  se define  la  vista  (el  mismo  que  el  res_model  de  las  acciones). .gantt--> <field name="priority" eval="16"/> <field name="arch" type="xml"> <!-. • Los campos se colocan en la pantalla de izquierda a derecha y de arriba a abajo. gantt..10: Vista en modo formulario. --> </field> </record> Donde: • id: Es el identificador único de la vista. calendar. Esta es la declaración genérica del registro XML de una vista: <record model="ir. separadores.calendar.1.ui. cuanto más pequeño. <tree>.. más prioridad (por defecto 16). • arch: Arquitectura o estructura de la vista. pestañas. .view content: <form>. • name: Nombre de la vista.form. • priority: Prioridad de la vista. • type: Tipo de vista: form.graph. Mediante etiquetas XML se define la composición de  la vista (etiquetas. campos. search. graph.3.name</field> <field name="model">object_name</field> <field name="type">form</field> <!--tree. cada campo es precedido por una etiqueta con su nombre. tree.

• Cada pantalla se divide en cuatro columnas. habrá dos campos (y sus respectivas etiquetas) en cada  línea de la pantalla. ilustran las cuatro columnas. En la figura 6.12. Figura 6. Un campo puede mostrarse en  varias columnas con el atributo colspan. Puesto que todos los campos de edición son precedidos (por  defecto) con una etiqueta con su nombre. que ocupa las cuatro columnas de la pantalla. se resalta en rojo un único campo con su  correspondiente etiqueta. . En la figura 6.11: Colocación por defecto de los campo y sus etiquetas en cuatro columnas. o bien una  etiqueta o bien un campo de edición. las zonas verdes y rojas.11. cada columna es capaz de contener. Pero las vistas también soportan opciones de colocación avanzadas.

. También se puede efectuar la operación contraria: tomar un grupo de columnas y dividirlas en las  columnas que se deseen con la etiqueta group y los atributos colspan y col. Finalmente.Figura 6. hay una forma de distribuir los campos de un objeto en diferentes pestañas (zona azul  de la figura 6.12: Una campo ocupa varias columnas.13) con las etiquetas notebook y page.

Figura 6. colspan: Sirve para indicar el número de columnas que debe abarcar el campo.ui. col: Número de columnas que este elemento debe asignar a sus elementos hijos. sirve para ocultar completamente este elemento. nolabel: Sirve para ocultar la etiqueta del campo (valor 1). a)  Módulo ejemplo academy Éste es el código para la vista de formulario classroom: <record model="ir.view" id="view_academy_classroom_form"> <field name="name">academy. rowspan: Sirve para indicar el número de filas que debe abarcar el campo.form</field> <field name="model">academy.13: Otra forma de mostrar los campos mediante pestañas.  invisible. eval: Evalúa este código Python como un contenedor de elemento (por defecto. invisible: Si su valor se establece a 1. required basados en tuplas de búsqueda u otros campos de valor. el contenedor es  una cadena) • attrs:   Asignación   Python   que   define   las   condiciones   dinámicas   de   estos   atributos:  readonly.classroom.classroom</field> <field name="type">form</field> <field name="arch" type="xml"> <form string="academy.classroom"> <field name="name" select="1"/> <field name="address_ids" select="2"/> <field name="capacity" /> <field name="state" /> <field name="active" /> </form> </field> </record> Donde los siguientes atributos son comunes a todos los elementos: string: Es la etiqueta del elemento. • • • • • • • .

password: True para ocultar los caracteres escritos en este campo. también para búsquedas (reemplaza el nombre del campo). pueden verse algunos ejemplos de widgets.   url.   reference. groups: Lista de grupos de usuarios separados por comas (id) autorizados a ver dicho campo. nolabel: 1 para ocultar la etiqueta del campo.14 a 6.20.14:  Los atributos específicos del campo field son: – – – – – – – – – – – string: Etiqueta del campo.   image.17: Widget number . context: Código Python para declarar un diccionario contextual.  Figura 6.   text_html.15:     Widget booleano Figura 6.16: Widget selection Figura 6. domain:   Código   Python   para   declarar   una   lista   de   tuplas   con   condiciones   para   restringir  valores (usado en campos relacionales). En las figuras 6.   float_time. Figura 6. widget:   Selecciona   un   widget   alternativo   al   proporcionado   de   forma   automática  (one2many_list.   text_wiki. required: Reemplaza al atributo “required” definido en el modelo.Los elementos que se pueden añadir en una vista pueden ser: field: Campos con su correspondiente widget según el tipo de campo. readonly: Reemplaza al atributo “readonly” definido en el modelo. select: 1 para mostrar el campo de búsqueda normal.  progressbar). on_change: Método Python que se ejecuta cuando se cambia el valor del campo.14 ).   many2many. Por ejemplo un campo de tipo  fecha tiene un widget con un calendario para poder seleccionar la fecha con comodidad (figura 6. 2 sólo para búsqueda avanzada.

  nombre   de   función   (sin   paréntesis)   o   acción   a   llamar  (dependiendo del tipo).19: Widget many2many Figura 6. confirm: Texto de mensaje de confirmación cuando se hace clic. por ejemplo gtk­ok). ∙ object: ∙ action: Tiene asociada una acción que se ejecuta cuando se hace clic sobre el botón.Figura 6. notebook. right (derecha).20: Widget url properties: Widget dinámico que muestra todas las propiedades disponibles. states: Lista de estados separados por comas. con etiqueta opcional. newline: Añade espacio en blanco para completar la línea actual de la vista y saltar a la siguiente. “object” o “action”. group: Utilizado para organizar campos en grupos con etiquetas opcionales (añade marco). ∙ workflow: Mediante este tipo se puede cambiar el estado del registro pasando por una serie  de estados predefinidos. Atributos específicos: – – – – – type: Tipo de botón. page: Los elementos notebook son contenedores de pestaña para los elementos page que  definen cada una de las pestañas. label: Título de texto libre o leyenda en el formulario. Este es el código para la vista de formulario de course: . left  (izquierda). • position: posición de la pestaña en el notebook: inside (dentro). bottom (abajo).18: Widget one2many Figura 6. top (arriba).  name:   Señal   de   flujo   de   trabajo. icon: Icono opcional (se pueden usar todos los iconos de GTK STOCK. button:   Widget   en   forma   de   botón   sobre   el   que   se   puede   hacer   clic   que   está   asociado   a  determinadas acciones. separator: Línea de separación horizontal para estructurar vistas. Atributos: • name: Etiqueta para la pestaña. en los que dicho botón se muestra. Puede ser “workflow” (flujo de trabajo ­por defecto­).

 ambos  campos aparecerán en las  opciones  de búsqueda. y el segundo (parent_id) en la búsqueda avanzada. • editable: top o botton para permitir editar el lugar en el que colocarlo.course</field> <field name="type">form</field> <field name="arch" type="xml"> <form string="academy.3.course.classroom</field> <field name="type">tree</field> <field name="arch" type="xml"> <tree string="academy.ui. group. • toolbar: Establecer a True para mostrar el nivel superior de la jerarquía de objetos como una  barra de herramientas lateral (por ejemplo. se crean con el tipo tree.ui. filter y newline. Los elementos permitidos son: field.course"> <field name="name" select="1"/> <field name="category_id" select="2"/> <field name="classroom_id" /> <field name="dificulty" /> <field name="hours" /> <field name="state" /> <field name="description" colspan="4" /> </form> </field> </record> Este es le código para la vista de tipo formulario de course_category: <record model="ir.<record model="ir. tree.category.form</field> <field name="model">academy.ui. Son más simples que las vistas de formulario y tienen menos  opciones.form</field> <field name="model">academy. los menús).tree</field> <field name="model">academy.view" id="view_academy_course_form"> <field name="name">academy.view" id="view_academy_classroom_tree"> <field name="name">academy.course.classroom"> . y tienen un elemento padre <tree> en  lugar de <form> usado anteriormente.category"> <field name="name" select="1"/> <field name="parent_id" select="2"/> </form> </field> </record> Como puede comprobarse. a)  Módulo ejemplo academy Este es el código para la vista de tipo lista de classroom: <record model="ir. separator.category</field> <field name="type">form</field> <field name="arch" type="xml"> <form string="academy. Entre los atributos que se le pueden añadir caben destacar los siguientes: • colors: Listas de colores mapeados a Python. 6. Incluyen elementos field. El primero  (name) en la búsqueda normal. button.  Vistas de lista o árbol Estas vistas se utilizan cuando se trabaja en modo lista (con objeto de visualizar varios recursos a la  vez) y en la pantalla de búsqueda.classroom.course.course.view" id="view_academy_course_category_form"> <field name="name">academy.2.

tree</field> <field name="model">academy.view" id="view_academy_course_tree"> <field name="name">academy.category"> <field name="name"/> <field name="parent_id"/> </tree> </field> </record> En   este  caso   puede  observarse   como  el   objeto  hace   referencia   a  sí  mismo   a  través   del   campo  parent_id.category.course</field> <field name="type">tree</field> <field name="arch" type="xml"> <tree string="academy.course. . La figura 6.course. El código de la vista de tipo lista de course_category es el siguiente: <record model="ir.category</field> <field name="type">tree</field> <field name="arch" type="xml"> <tree string="academy.ui.view" id="view_academy_course_category_tree"> <field name="name">academy.course. Este es el código de la vista de tipo lista de curso: <record model="ir.tree</field> <field name="model">academy.<field <field <field <field <field </tree> </field> </record> name="name"/> name="address_ids"/> name="capacity"/> name="state"/> name="active"/> Como puede comprobarse.course.course"> <field name="name"/> <field name="category_id"/> <field name="classroom_id"/> <field name="dificulty"/> <field name="hours"/> <field name="state"/> <field name="description"/> </tree> </field> </record> En este caso puede comprobarse como se hace referencia a los objetos  category  y  classroom  a  través de los campos category_id y classroom_id. se mostrarán cinco campos.21 muestra el resultado del código anterior.ui.

.21: Ejemplo de Vista de lista o árbol.Figura 6.

  STOCK_DND.   STOCK_MEDIA_PREVIOUS.   STOCK_PRINT_PREVIEW. STOCK_DIALOG_ERROR.   STOCK_STOP.   STOCK_EDIT. STOCK_ZOOM_OUT.  STOCK_DIALOG_QUESTION.   STOCK_COPY.  STOCK_CONNECT.   STOCK_UNDELETE.   STOCK_OPEN.  STOCK_CDROM.  terp­hr.  STOCK_MEDIA_REWIND.   STOCK_FIND. terp­account.7.   STOCK_INDENT. STOCK_REMOVE.  STOCK_GO_UP. terp­project.   STOCK_JUSTIFY_LEFT.STOCK_REDO.  STOCK_MEDIA_PLAY.  STOCK_SELECT_COLOR.   STOCK_DELETE.   STOCK_YES. Lista de iconos disponibles para el parámetro icon de las vistas XML.   STOCK_NO.   STOCK_CONVERT.   STOCK_MEDIA_NEXT. terp­partner.   STOCK_GO_BACK.   STOCK_JUSTIFY_RIGHT.   STOCK_SORT_ASCENDING.   STOCK_HOME.   STOCK_MEDIA_STOP.   STOCK_SELECT_FONT.   STOCK_GOTO_BOTTOM.  terp­report.   STOCK_SAVE_AS.  STOCK_PASTE.  STOCK_REVERT_TO_SAVED.  STOCK_JUSTIFY_FILL.   STOCK_CLEAR.   STOCK_CLOSE.   STOCK_OK.   STOCK_DIRECTORY. terp­ purchase.   STOCK_HARDDISK.  terp­tools.   STOCK_SPELL_CHECK. STOCK_REFRESH.   STOCK_JUSTIFY_CENTER.   STOCK_ADD.  terp­administration.  STOCK_GOTO_TOP.  STOCK_DIALOG_AUTHENTICATION.   STOCK_MEDIA_RECORD.   STOCK_DND_MULTIPLE.  STOCK_INDEX. STOCK_QUIT.  STOCK_UNINDENT.   STOCK_NEW.  STOCK_DISCONNECT.   STOCK_MISSING_IMAGE. terp­crm.  STOCK_EXECUTE.  STOCK_NETWORK.   STOCK_APPLY. terp­product.   STOCK_JUMP_TO.   STOCK_HELP. STOCK_DIALOG_INFO.   STOCK_SAVE.   STOCK_ZOOM_100.   STOCK_GOTO_FIRST.   STOCK_BOLD. terp­mrp.  terp­stock .  Anexo 1.   STOCK_ITALIC.   STOCK_FIND_AND_REPLACE.  STOCK_PROPERTIES.  terp­sale.  STOCK_ZOOM_IN.   STOCK_GOTO_LAST.   STOCK_ZOOM_FIT.   STOCK_UNDO.  STOCK_FLOPPY.  STOCK_MEDIA_FORWARD.   STOCK_GO_DOWN.   STOCK_CUT.   STOCK_CANCEL. STOCK_ABOUT.   STOCK_COLOR_PICKER.   STOCK_GO_FORWARD.   STOCK_UNDERLINE.   STOCK_MEDIA_PAUSE.   STOCK_DIALOG_WARNING.   STOCK_PREFERENCES.  STOCK_STRIKETHROUGH.   STOCK_FILE.   STOCK_PRINT.  STOCK_SORT_DESCENDING.

Sign up to vote on this title
UsefulNot useful