This is the documentation for older versions of Odoo (formerly OpenERP).

See the new Odoo user documentation.

See the new Odoo technical documentation.

模块结构

模块

  1. 简介

  2. 文件和文件夹结构
    1. __openerp__.py

    2. __init__.py

    3. XML 文件
      1. 操作

      2. Menu Entries

      3. Reports

      4. 向导

  3. 配置文件

模块 - 文件和文件夹结构

所有模块都应放到 server/addons 文件夹下。

按下面步骤创建新模块:

  • 在 server/addons 文件夹下面创建模块子文件夹

  • 创建模块定义文件: __openerp__.py

  • 创建定义 objectsPython 文件

  • 创建包括(初始数据, 视图, 菜单, 演示数据)的 .xml 文件

  • 创建包含 reports, wizardsworkflows 的 xml文件(可选)

模块 - 文件和目录 - XML 文件

模块目录里的XML文件用于修改数据库结构,他们有很多的用途,我们可以列出来:

  • 初始化,实例化(demonstration)数据声明(declaration)

  • 视图声明

  • 报表声明

  • 向导声明

  • 工作流声明

OpenERP XML文件主要结构的更多细节在 XML 数据序列化 部分,如果你想学习更多关于*初始化* 和 示例数据 XML文件,可以查看这里。 下面的部分只是关于特定的XML文件,如 following section are only related to XML specific to actions, menu entries, *操作、菜单、报表、向导工作流 定义。

Python 模块描述文件 __init__.py

** __init__.py 文件**

这个文件就像任何的Python模块中一样,在程序的开始运行。它负责导入程序所需的Python文件。

所以,如果你想创建一个“module.py”文件,它包括你的对象的描述,在这种情况下,你需要在__init__.py文件中写一行:

import module

OpenERP 模块描述文件 __openerp__.py

在已创建模块的目录下,你必须添加一个__openerp__.py文件。这个文件必须在Python的格式下,负责:

  1. 确定所需的XML文件,server在进行初始化时将从语法上分析这些文件。

  2. 确定该创建模块的依赖模块。

这个文件包括下面的值:

name

(英文)名称.

version

版本

description

描述

author

模块的作者

website

模块的网站

license

模块的授权协议(默认AGPL).

depends

列出该模块所依赖的其他模块,因为base模块包括模块必须的视图,报表等数据,所以base模块应该在其他所有模块的依赖中。

init_xml

List of .xml files to load when the server is launched with the "--init=module" argument. Filepaths must be relative to the directory where the module is. OpenERP XML File Format is detailed in this section.

update_xml

List of .xml files to load when the server is launched with the "--update=module" launched. Filepaths must be relative to the directory where the module is. OpenERP XML File Format is detailed in this section.

installable

True或是False,决定这个模块是否可安装。

active

True或是False(默认是False),决定这个模块在数据库创建时是否安装。

范例

以product模块中的__openerp__.py为例:

{
    "name" : "Products & Pricelists",
    "version" : "1.1",
    "author" : "Open",
    "category" : "Generic Modules/Inventory Control",
    "depends" : ["base", "account"],
    "init_xml" : [],
    "demo_xml" : ["product_demo.xml"],
    "update_xml" : ["product_data.xml", "product_report.xml", "product_wizard.xml",
                    "product_view.xml", "pricelist_view.xml"],
    "installable": True,
    "active": True
}

放置在init_xml中的文件必须要么是和工作流相关,要么是安装软件时装载数据相关,或是和示例数据相关。

update_xml中的文件涉及到视图,报表和向导。

Objects

所有OpenERP的资源都是对象,如menus,actions,reports,invoices,partners... OpenERP通过数据库的对象关系映射(ORM,object relational mapping of a database)来控制信息存储。OpenERP的对象名是层次结构的,例如:

  • account.transfer : a money transfer

  • account.invoice : an invoice

  • account.invoice.line : an invoice line

总之,第一个单词是模块的名字:account,stock,sale

ORM的其他优点有:

  • simpler relations : invoice.partner.address[0].city

  • objects have properties and methods: invoice.pay(3400 EUR),

  • inheritance, high level constraints, ...

操作一个对象比很多表要容易些。

/doc_static/6.0/_images/pom_3_0_3.png

The Physical Objects Model of [OpenERP version 3.0.3]

PostgreSQL

OpenERP的ORM是在PostgreSQL上构造的。在OpenERP上通过对象接口或是直接使用SQL语句查询一个对象是可行的。

在PostgreSQL数据库中直接进行读写是非常危险的,因为可能会漏掉重要的步骤如约束检查或是工作流的修改。

注解

The Physical Database Model of OpenERP

Pre-Installed Data

PostgreSQL表中的数据可以使用XML文件来进行插入或更新,使得于OpenERP对象数据一致。OpenERP XML文件的主要结构是:

<?xml version="1.0"?>
<openerp>
  <data>
    <record model="model.name_1" id="id_name_1">
      <field name="field1">
        "field1 content"
      </field>
      <field name="field2">
        "field2 content"
      </field>
      (...)
    </record>
    <record model="model.name_2" id="id_name_2">
        (...)
    </record>
    (...)
  </data>
</openerp>

Fields content are strings that must be encoded as UTF-8 in XML files.

下面是一个来自 OpenERP 的源码的例子 (base_demo.xml 在 base 模块中):

<record model="res.company" id="main_company">
    <field name="name">Tiny sprl</field>
    <field name="partner_id" ref="main_partner"/>
    <field name="currency_id" ref="EUR"/>
</record>
<record model="res.users" id="user_admin">
    <field name="login">admin</field>
    <field name="password">admin</field>
    <field name="name">Administrator</field>
    <field name="signature">Administrator</field>
    <field name="action_id" ref="action_menu_admin"/>
    <field name="menu_id" ref="action_menu_admin"/>
    <field name="address_id" ref="main_address"/>
    <field name="groups_id" eval="[(6,0,[group_admin])]"/>
    <field name="company_id" ref="main_company"/>
</record>

最后的字段定义的 admin user :

  • 登录,密码等字段比较直接.

  • ref属性用于在records之间建立关系

<field name="company_id" ref="main_company"/>

字段company_id是一个从user object到company object的many-to-one的关系,main_company是相关联的id。

  • eval 属性允许将一些 python 代码放进 xml 中: 这里 groups_id 字段是一个多对多(many2many)的关系. 对于这样一个字段, "[(6,0,[group_admin])]" 的意思为 : 删除所有与当前用户相关的组,并使用 [group_admin] 作为新的关联组 (and group_admin 是另一个记录的 id ).

  • search 属性允许你在不指定 xml id 的情况下. 查找相关的记录. 你可以指定一个搜索条目来寻找想要查询的字段. 条目是一个 tuple 的 lists 用于预定义的搜索方法, 如果有多个结果, 通常选中(第一个):

<field name="partner_id" search="[]" model="res.partner"/>

这是个在demo数据中使用search的典型例子。在这里我们并不是真正想知道是哪个partner,所以我们给出了一个空的list。注意model属性是在一般情况下必须要写的。

记录标签

Description

T新数据的添加是通过record标签实现的。它利用一个必备的属性:model。Model是一个对象名称,可以用来实现插入数据。record标签内还有一个可选择的属性:id。如果使用了这个属性,那么在相同文件中,这个名字可以代替新创建的资源ID。

record标签中包含field标签。他们指出record的字段值(record’s fields value)。如果这个field没有详细说明,那么它会使用默认值。

范例

<record model="ir.actions.report.xml" id="l0">
     <field name="model">account.invoice</field>
     <field name="name">Invoices List</field>
     <field name="report_name">account.invoice.list</field>
     <field name="report_xsl">account/report/invoice.xsl</field>
     <field name="report_xml">account/report/invoice.xml</field>
</record>

Field tag

对应的属性如下:

name : (必需) : mandatory

field name

eval : (可选) : optional

将指定值进行添加的python表达式

ref

这个文件中涉及到已定义的id

model

用于查找的model

search

查询

Function tag

一个功能标签包含其他的功能标签。

model : (必须有的) : mandatory

要调用的model

name : (必需) : mandatory

function的名称

eval

估值(evaluate)要调用的方法的参数列表,不计cr和uid

范例

<function model="ir.ui.menu" name="search" eval="[[('name','=','Operations')]]"/>

Getitem tag

采用标签最后一个子节点的子集.

type : (必需) : mandatory

int 或 list

index : (必需) : mandatory

int or string

范例

Evaluates to the first element of the list of ids returned by the function node

<getitem index="0" type="list">
    <function model="ir.ui.menu" name="search" eval="[[('name','=','Operations')]]"/>
</getitem>

i18n

改进翻译

Translating in launchpad

翻译由“Launchpad Web interface”管理。在这里你会找到可译项目的清单。

请在问问题前阅读 FAQ

Translating your own module

在 5.0 版更改.

和之前4.2.x的版本不同,现在翻译都是通过模块来做。所以和之前整个系统中有一个特殊i18n文件夹不同的是,现在每一个模块都有自己的i18n文件夹。此外,OpenERP可以处理.po文件作为导入导出格式。当我们安装或是更新一个模块时,安装语言的翻译文件可以自动装入系统中。OpenERP也可以产生一个.tgz文件归档,里面包括为每个选中模块组织很好的.po文件。

[1]

http://www.gnu.org/software/autoconf/manual/gettext/PO-Files.html#PO-Files

Process

Defining the process

通过界面(interface)或是模块recorder来定义进程。然后放置生成的XML文件在自己的模块中。

Views

Technical Specifications - Architecture - Views

视图是一种在客户端显示对象的方式。他们指示客户端如何在屏幕上显示对象数据。

视图有两种:

  • 表单视图

  • 列表视图

Lists是tree views中的特殊情形。

同一个对象有几种视图:首先定义的视图样式(tree,form,…)将会做为它默认的样式。那样的话,当你双击一个菜单项时,就有一个默认的tree view和一个特定的view显示差不多的信息。例如,products针对product变量有几种视图。

视图都是在XML文件中进行描述的。

如果一个对象没有定义视图,那么这个对象可以自己产生一个视图来显示它自己。这会限制开发者的工作,但是会导致较少的人们自己的视图设计(ergonomic views)。

Usage example

当我们打开一张发票时,接下来是在客户端上的操作:

  • 一个动作请求打开发票(它给出了一个对象的数据(account.invoice),视图,域(例如仅仅是还未付款的发票))

  • 客户端请求server,什么样的视图由发票对象定义,哪些数据要显示。

  • 客户端通过视图显示表单

/doc_static/6.0/_images/arch_view_use.png

To develop new objects

对新对象的设计限制到最低限度:创建对象并且有选择的创建视图来显示他们。PostgreSQL的table数据不用手写,因为对象会自动创建它们(除非它们已经存在)。

Reports

OpenERP使用一个非常灵活和强大的报表系统。报表以PDF或是HTML的形式生成。报表是以数据层和表现层分开的原理进行设计的。

关于报表更多的细节在 Reporting 章节。

向导

这里有个描述向导的.xml文件的例子:

<?xml version="1.0"?>
<openerp>
    <data>
     <wizard string="Employee Info"
             model="hr.employee"
             name="employee.info.wizard"
             id="wizard_employee_info"/>
    </data>
</openerp>

wizard用wizard标签来声明。想要知道更多关于wizard XML的信息可以查看“Add A New Wizard”这个章节。

或者你可以在菜单中通过使用下面的XML entry添加向导。

<?xml version="1.0"?>
</openerp>
     <data>
     <wizard string="Employee Info"
             model="hr.employee"
             name="employee.info.wizard"
             id="wizard_employee_info"/>
     <menuitem
             name="Human Resource/Employee Info"
             action="wizard_employee_info"
             type="wizard"
             id="menu_wizard_employee_info"/>
     </data>
</openerp>

Workflow

通过对象和视图,我们可以很简单的定义新的表单,lists/trees和它们间的交互。但是这还不够:你还得定义这些对象间的动态关系。

举个例子:

  • 在一般的情况下,一个已确定的销售订单必须生成一张发货单。

  • 只是在确认发货单已付款的前提下,才会开出运送清单。

工作流使用图表描述这些交互,一个或几个工作流相关到对象。工作流是非必须的;一些对象就没有工作流。

下面的工作流用于销售订单的例子。在一定的条件下,它必须产生发货单和出货。

/doc_static/6.0/_images/arch_workflow_sale.png

在这张图表中节点代表着要做的动作。

  • 创建发票

  • 取消销售订单

  • 生成装货单, ...

上面的箭头代表条件:

  • 等待订单获得批准

  • 发票支付

  • 点击取消按钮,。。。

方格样式的节点代表其他的工作流:

  • 发票

  • 发货