odoo之ERP系统
odoo大纲
第一部分:数据库postgressql 大象
第二部分:ORM(API)
第三部分:客户端
用python软件写:
.py文件
包含两部分:1、自定义部分,由自己写,定义类和功能。
、继承部分,针对的是原生的模块,继承他原有的功能,添加新的方法。
.xml文件
视图部分:最常用的是form视图和tree视图,等等其他视图,还有页签和其他控件按钮
Openerp 基本数据类型:
char: 字符型,size属性定义字符串长度。
text:
文本型,没有长度限制。
boolean:
布尔型(true,
false)
integer: 整数。
float:
浮点型,如
'rate'
: fields.float('Relative Change rate',digits=(12,6)),
digits定义整数部分和小数部分的位数。
date:
日期型
time:
时间型
datetime:
日期时间型
binary:
二进制型
复杂类型:selection,
function, related, reference;
selection
Python代码 aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAOCAYAAADwikbvAAAACXBIWXMAAC4jAAAuWAG0bp9LAAAByElEQVR4nI1SyavBURT+8CNDSUqxMGRaGJIhZKGUrOwk7P1rNkqGhQWxVAplHpKhFKWI2Mjw3r0vr+c9i/etzjn3fPc79zuX2e/3D7xBo9FAqVSCy+VCKBR61wLmbfUT7XYbbDYb3W4XXq8XYrH4f+T1eo3NZoNwOIxKpYLRaAS32/0/MlElSjabDbPZjOZvyavVCsPhENfr9bvYbDbh8XhorFar0Wq1kMvlIBAIcL/fwWKxaJ1Jp9M4nU7QarX04Ha7QalUwmg0UrJGo4HJZMKnsTgcDuByuSCCZBqGNA4GA+h0OqpGTPoJqVSKRCLxnY/HYywWCygUCjDRaJSOVSgUUK/XEYvF6MFvHI9HOvpkMoHf70cgEPgyzOFwQCKRoFwuI5VKIZlM0vyJx+OBTCaD7XaLSCQCu93+6jZ5s16vR6fTgVAofFElBolEIho/iS/ky+WCXq8Hi8UCHo+H6XSKWq0Gs9kMp9MJg8FAn0b2L5fLX8nL5RK73Q4qlYqq5/N56ux8Pqd14jiHw0G/3/9LJo4Tp6vVKv1hwWAQPp+P/oFsNktd5vP59LI/Y5OVkVHJnuPxOFUisFqtkMlkKBaLOJ/PtO+JD60fxMgd8/W4AAAAAElFTkSuQmCC" alt="收藏代码" name="图像1" width="15" height="14" align="bottom" border="0" />
selection: 下拉框字段。定义一个下拉框,允许用户选择值。如:'state': fields.selection((('n','Unconfirmed'),('c','Confirmed')),'State', required=True),这表示state字段有两个选项('n','Unconfirmed')和('c','Confirmed')。
function
Python代码 aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAOCAYAAADwikbvAAAACXBIWXMAAC4jAAAuWAG0bp9LAAAByElEQVR4nI1SyavBURT+8CNDSUqxMGRaGJIhZKGUrOwk7P1rNkqGhQWxVAplHpKhFKWI2Mjw3r0vr+c9i/etzjn3fPc79zuX2e/3D7xBo9FAqVSCy+VCKBR61wLmbfUT7XYbbDYb3W4XXq8XYrH4f+T1eo3NZoNwOIxKpYLRaAS32/0/MlElSjabDbPZjOZvyavVCsPhENfr9bvYbDbh8XhorFar0Wq1kMvlIBAIcL/fwWKxaJ1Jp9M4nU7QarX04Ha7QalUwmg0UrJGo4HJZMKnsTgcDuByuSCCZBqGNA4GA+h0OqpGTPoJqVSKRCLxnY/HYywWCygUCjDRaJSOVSgUUK/XEYvF6MFvHI9HOvpkMoHf70cgEPgyzOFwQCKRoFwuI5VKIZlM0vyJx+OBTCaD7XaLSCQCu93+6jZ5s16vR6fTgVAofFElBolEIho/iS/ky+WCXq8Hi8UCHo+H6XSKWq0Gs9kMp9MJg8FAn0b2L5fLX8nL5RK73Q4qlYqq5/N56ux8Pqd14jiHw0G/3/9LJo4Tp6vVKv1hwWAQPp+P/oFsNktd5vP59LI/Y5OVkVHJnuPxOFUisFqtkMlkKBaLOJ/PtO+JD60fxMgd8/W4AAAAAElFTkSuQmCC" alt="收藏代码" name="图像2" width="15" height="14" align="bottom" border="0" />
#函数型,该类型的字段,字段值由函数计算而得,不存储在数据表中。其定义格式为:
fields.function(fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='float', fnct_search=None, obj=None, method=False, store=True)
#· type 是函数返回值的类型。
#· method 为True表示本字段的函数是对象的一个方法,为False表示是全局函数,不是对象的方法。如果method=True,obj指定method的对象。
#· fcnt 是函数或方法,用于计算字段值。如果method = true, 表示fcnt是对象的方法,其格式如下:def fnct(self, cr, uid, ids, field_name, args, context),否则,其格式如下:def fnct(cr, table, ids, field_name, args, context)。ids是系统传进来的当前存取的record id。field_name是本字段名,当一个函数用于多个函数字段类型时,本参数可区分字段。args是'arg=None'传进来的参数。
#· fcnt_inv是用于写本字段的函数或方法。如果method = true, 其格式是:def fcnt_inv(self, cr, uid, ids, field_name, field_value, args, context),否则格式为:def fcnt_inv(cr, table, ids, field_name, field_value, args, context)
#· fcnt_search 定义该字段的搜索行为。如果method = true, 其格式为:def fcnt_search(self, cr, uid, obj, field_name, args),否则格式为:def fcnt_search(cr, uid, obj, field_name, args)
#· store 表示是否希望在数据库中存储本字段值,缺省值为False。不过store还有一个增强形式,格式为 store={'object_name':(function_name,['field_name1','field_name2'],priority)} ,其含义是,如果对象'object_name'的字段['field_name1','field_name2']发生任何改变,系统将调用函数function_name,函数的返回结果将作为参数(arg)传送给本字段的主函数,即fnct。
Python代码 related
#关联字段,表示本字段引用关联表中的某字段。
格式为:fields.related(关系字段,引用字段,type, relation, string, ...),关系字段是本对象的某字段(通常是one2many or many2many),引用字段是通过关系字段关联的数据表的字段,type是引用字段的类型,
如果type是many2one or many2many, relation指明关联表。例子如下:
'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts'),
'city':fields.related('address','city',type='char', string='City'),
'country':fields.related('address','country_id',type='many2one', relation='res.country', string='Country'),
这里,city引用address的city字段,country引用address的country对象。在address的关联对象res.partner.address中,country_id是many2one类型的字段,所以type='many2one', relation='res.country'。
reference
引用型,格式为:fields.reference(字段名,
selection, size, ... )。其中selection是:
1)返回tuple列表的函数,或者
2)表征该字段引用哪个对象(or
model)的tuples列表。reference字段在数据库表中的存储形式是(对象名,ID),如(product.product,3)表示引用对象product.product(数据表product_product)中id=3的数据。reference的例子:
def
_links_get(self, cr, uid):
cr.execute('select object,name from
res_request_link order by priority')
return
cr.fetchall()
...
'ref':fields.reference('Document
Ref 2', selection=_links_get,
size=128),
...
上例表示,字段ref可以引用哪些对象类型的resource,可引用的对象类型从下拉框选择。下拉框的选项由函数_links_get返回,是(object,name)对的列表,如[("product.product","Product"),
("account.invoice","Invoice"),
("stock.production.lot","Production Lot")] 。
关系类型:one2one,
one2many, many2one, many2many
Openerp
one2one:
一对一关系,格式为:fields.one2one(关联对象Name,
字段显示名,
... )。在V5.0以后的版本中不建议使用,而是用many2one替代。
many2one:
多对一关系,格式为:fields.many2one(关联对象Name,
字段显示名,
...
)。可选参数有:ondelete,可选值为"cascade"和"null",缺省值为"null",表示one端的record被删除后,many端的record是否级联删除。
one2many:
一对多关系,格式为:fields.one2many(关联对象Name,
关联字段,
字段显示名,
... ),例:'address':
fields.one2many('res.partner.address', 'partner_id',
'Contacts')。
many2many:
多对多关系。例如:
'category_id':fields.many2many('res.partner.category','res_partner_category_rel','partner_id','category_id','Categories'),
表示以多对多关系关联到对象res.partner.category,关联表为'res_partner_category_rel',关联字段为'partner_id'和'category_id'。当定义上述字段时,OpenERP会自动创建关联表为'res_partner_category_rel',它含有关联字段'partner_id'和'category_id'。
change_default:别的字段的缺省值是否可依赖于本字段,缺省值为:False。例子(参见res.partner.address),
'zip':
fields.char('Zip', change_default=True,
size=24),
这个例子中,可以根据zip的值设定其它字段的缺省值,例如,可以通过程序代码,如果zip为200000则city设为“上海”,如果zip为100000则city为“北京”。
readonly:
本字段是否只读,缺省值:False。
required:
本字段是否必须的,缺省值:False。
states:
定义特定state才生效的属性,格式为:{'name_of_the_state':
list_of_attributes},其中list_of_attributes是形如[('name_of_attribute',
value), ...]的tuples列表。例子(参见account.transfer):
'partner_id':
fields.many2one('res.partner', 'Partner',
states={'posted':[('readonly',True)]}),
string:
字段显示名,任意字符串。
translate:
本字段值(不是字段的显示名)是否可翻译,缺省值:False。
size:
字段长度。
priority:
domain:
域条件,缺省值:[]。在many2many和many2one类型中,字段值是关联表的id,域条件用于过滤关联表的record。例子:
'default_credit_account_id':
fields.many2one('account.account', 'Default Credit Account',
domain="[('type','!=','view')]"),
本例表示,本字段关联到对象('account.account')中的,type不是'view'的record。
invisible:
本字段是否可见,即是否在界面上显示本字段,缺省值True。
selection:
只用于reference字段类型,参见前文reference的说明
Attributs
说明
•context:
在context
中增加一些变量,这些变量可用于on_change方法及domain条件式。
•on_change:
当本字段值改变时,调用Server端函数。例子:
on_change=”onchange_shop_id(shop_id)”.
•relation:当本字段是一个引用其他数据表的id
时,指定关联数据表名。通常用在related
和
function
类型的字段中。
•
级联关系:
•ondelete
•set
null: 删除主记录时候,从记录到主记录的引用置为null。
•set
default: 删除主记录时候,从记录到主记录的引用置为缺省值。
•cascade:
删除主记录时候,级联删除从记录。
•restrict:
如果有从记录,不允许删除主记录。
•no
action: 不采取任何动作,即删除主记录,但保留从记录不变。
模板中的标签统一都是以"t-"开始的。
t-name
用于指明模板的名称
t-extend
用于指明该模板是继承自另外哪一个模板,后面会带父模板的名称,如:t-extend=“Login"
t-jQuery
一个jQuery的选择器,后面指明选择器的定义,如:t-jquery=".oe_logiin"
t-operation
一般跟在t-jquery后面,指明选择器找到元素后执行的动作,其值有:append(追加)、replace(替换)
t-if
用于指明元素在页面产生的条件,后面是带一个JavaScript的表达式,返回True或False
t-att-###
用于指明一个元素的属性值,###是元素的属性名称,如:t-att-value="javascript表达式"
t-foreach
用于指明一个循环调用,后面一般带的是一个数组
t-as
用于取得循环中的单个值,与t-foreach搭配使用,后面带的是一个变量名,可以循环中使用变量取值
t-esc
用于一个文字输出
t-call
用于调用另外模板,后面带一个模板的名称
t-set
用于设定一个变量,后面带变量的名称,一般跟t-value搭配使用
t-value
用于指定某个变量或元素的值
然后就是基本的函数:
python常用方法集合:
_get:
def get_partner_sequence(self,cr,uid,partner_id,context=None):
code="stock_picking_outgoing_no_%d" %(partner_id)
no=self.pool.get('ir.sequence').get(cr, uid, code, context=context)
if no==False:
self.create_new_sequence(cr,uid,code,partner_id)
no=self.pool.get('ir.sequence').get(cr, uid, code, context=context)
partner_ids=self.pool.get('res.partner').search(cr,uid,[('id','=',partner_id)])
partner_obj=self.pool.get('res.partner').browse(cr,uid,partner_ids)
no = "%s-%s" %(partner_obj.code,no)
return no
-crete:
def create(self, cr, uid, vals, context=None):
context = context or {}
origin=vals['origin']
sql='select a.name from sale_origin a left join sale_order b on a.id=b.sale_origin_id where b.name=\'%s\''%(origin)
cr.execute(sql)
if cr.rowcount>0:
dict1=cr.dictfetchall()[0]
origin=dict1['name']+'-'+origin
vals.update({'origin':origin})
sql='select a.name from purchase_origin a left join purchase_order b on a.id=b.purchase_origin_id where b.name=\'%s\''%(origin)
cr1=cr
cr1.execute(sql)
if cr1.rowcount>0:
dict2=cr1.dictfetchall()[0]
origin=dict2['name']+'-'+origin
vals.update({'origin':origin})
ptype_id = vals.get('picking_type_id', context.get('default_picking_type_id', False))
ptype_obj=self.pool.get('stock.picking.type').browse(cr, uid, ptype_id, context=context)
obj_data = self.pool.get('ir.model.data')
location_customers_id = obj_data.xmlid_to_res_id(cr, uid, 'stock.stock_location_customers')
location_workshop_id = obj_data.xmlid_to_res_id(cr, uid, 'mrp.stock_location_workshop')
# 根据客户来生成不同的编号
if ptype_obj.default_location_dest_id.id==location_customers_id \
and ptype_obj.code=='outgoing' \
and ptype_obj.default_location_src_id.id!=location_workshop_id:
if ('name' not in vals) or (vals.get('name') in ('/', False)):
partner_id = vals.get('partner_id')
vals['name'] = self.get_partner_sequence(cr,uid,partner_id)
new_id=super(stock_picking, self).create(cr, uid, vals, context)
self.action_confirm(cr, uid, [new_id], context=context)
return new_id
_write方法:
#修改单据下的日期和单头一样
def write(self,cr,uid,ids,vals,context=None):
if 'date_done' in vals and vals.get('date_done'):
obj=self.pool('stock.move')
move_ids=obj.search(cr,uid,[('picking_id','=',ids[0])])
obj.write(cr,uid,move_ids,{'date':vals.get('date_done')})
return super(stock_picking, self).write(cr, uid,ids, vals, context) _brown方法和search方法用法: def action_create_wave(self,cr,uid,ids,context=None):
if not context:
context={}
selfobj=self.browse(cr,uid,ids[0],context=context)
pickids=pickobj.search(cr,uid,[('origin','like',selfobj.name)])
.......
.......
....... 大致用法就是这样 默认信息带出来的写法:
_defaults={
'product_qty':1,
'price':1,
'stste':'draft',
} get-search-browse方法共用 点击备注id带出他的内容:
def sale_requirements_change(self,cr,uid,ids,requirements_id=None,context=None):
result={}
if requirements_id:
require_ids=self.pool.get('custorment.requirement').search(cr,uid,[('id','=',requirements_ids)])
obj=self.pool.get('custorment.requirement').browse(cr,uid,require_ids,context=None)
result['requirement_text']=obj.name
else:
result['requirement_text']=return{'value':result} name_search: 固定用法
# 输入工序序号会自动带出工序名
def name_search(self, cr,user,name='', args=None, operator='ilike', context=None, limit=):
if not args:
args=[]
args=args[:]
ids=[]
if name:
ids=self.search(cr,user,[('sequence','ilike',name)]+args,limit=limit,context=context)
else:
ids=self.search(cr,user,args,limit=limit,context=context)
return self.name_get(cr,user,ids,context)class:
用法
class
mrp_routing_workcenter_ref(osv.osv):
_inherit='mrp.routing.workcenter'
_columns={
'ban_channeng':fields.float(u'班产能',digits=(5,1)),
'machine_id':fields.many2one('mrp.machine',u'机台'),
'user_id':fields.many2one('res.users',u'工人'),
'workcenter_proline':fields.one2many('routing.workcenter.price','workcenter_proid',u'单身关联', copy=True),
'produce_description':fields.char(u'工序描述',),
'yjweight':fields.float(string=u'应交重量',digits=(6,2)),
}
_defaults={
'produce_description':'',
}
取消关联
def
unlink(
self
, cr, uid, ids, context=
None
):
sale_origins = self.read(cr, uid, ids, ['state'], context=context)
unlink_ids = []
for s in sale_origins:
if s['state'] in ['draft','cancel']:
unlink_ids.append(s['id'])
else:
raise osv.except_osv((u'警告!'),(u'已确认订单不可删除'))
return osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
odoo之ERP系统的更多相关文章
- 开源ERP系统Odoo搭建文档
本文参考链接地址: https://devecho.com/v/209/ https://www.cnblogs.com/wxylog/p/6386974.html 什么是Odoo 为什么选择Odoo ...
- 解析大型.NET ERP系统 权限模块设计与实现
权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少.总结我接触过的权限模块,以享读者. 1 权限的简明定义 ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事. 文句 含义 ...
- 解析大型.NET ERP系统 单据编码功能实现
单据编码是ERP系统中必备的功能,用于生成各种单据的流水号,常常借助于日期时间等字符来生成一个唯一的单据号码.从软件的角度来说,就是为生成数据表的主键值(参考编号),从用户的角度来说,就是给业务单据制 ...
- 解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
ERP系统的单据具备标准的功能,这里的单据可翻译为Bill,Document,Entry,具备相似的工具条操作界面.通过设计可复用的基类,子类只需要继承基类窗体即可完成单据功能的程序设计.先看标准的销 ...
- 解析大型.NET ERP系统 设计异常处理模块
异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性.下面从我理解的角度,谈谈异常处理的方方面面.我的设计仅仅限定于Windows Forms,供参考. 1 定义异常类型 . ...
- 解析大型.NET ERP系统 业务逻辑设计与实现
根据近几年的制造业软件开发经验,以我开发人员的理解角度,简要说明功能(Feature)是如何设计与实现的,供参考. 因架构的不同,技术实现上会有所差异,我的经验仅限定于Windows Form程序. ...
- 解析大型.NET ERP系统 数据审计功能
数据审计,英语表达是Audit,是追踪数据变化的过程,记录数据变化前后的值,供参考分析.通过设置,ERP可以追踪一个表的所有字段的变化,也可以只记录指定的字段的值变化.欧美企业每年都有独立的审计部门, ...
- 解析大型.NET ERP系统 十三种界面设计模式
成熟的ERP系统的界面应该都是从模板中拷贝出来的,各类功能的界面有规律可遵循.软件界面设计模式化或是艺术性的创作,我认可前者,模式化的界面客户容易举一反三,降低学习门槛.除了一些小部分的功能界面设计特 ...
- 解析大型.NET ERP系统 界面与逻辑分离
Windows Forms程序实现界面与逻辑分离的关键是数据绑定技术(Data Binding),这与微软推出的ASP.NET MVC的原理相同,分离业务代码与界面层,提高系统的可维护性. 数据绑定 ...
随机推荐
- BZOJ3108 [cqoi2013]图的逆变换
Description 定义一个图的变换:对于一个有向图\(G=(V, E)\),建立一个新的有向图: \(V'=\{v_e|e \in E\}\),\(E'=\{(v_b, v_e)|b=(u,v) ...
- Django使用多个数据库
一.定义数据库 使用Django的多个数据库的第一步是告诉Django将使用的数据库服务器. 这是使用DATABASES设置完成的. 此设置将数据库别名映射到该特定连接的设置字典,该数据库别名是一种在 ...
- 如何在Oracle数据库中查看哪些用户在执行哪些SQL
对于DBA来说,这是一个非常常见的问题,DBA需要找出以下问题: 1.哪些用户在跑哪些SQL? 2.一个特定的SQL是被哪个用户在执行? 3.一个特定的用户在跑哪些SQL? 从这些问题中可以很明显的看 ...
- 实验:JS判断浏览器中英文版本
<script type="text/javascript"> var lang = (navigator.systemLanguage?navigator.syste ...
- DrawerLayout建立侧滑时,显示侧滑页面,底层页面仍可以有点击响应,解决办法。
第一感觉是下层仍有焦点,解决办法应该是侧方页面出现后,下层页面的焦点改为false,应该是动态去改变焦点的状态,但是不知道如何去实现. 然后再网上找到实现方法,感谢:http://blog.csdn. ...
- RecyclerView打造通用的万能Adapter
既然想做到通用那么现在摆在面前的就三个问题:数据怎么办?布局怎么办? 绑定怎么办?.数据决定采用泛型,布局打算直接构造传递,绑定显示效果肯定就只能回传. 1 基本改造 数据决定采用泛型,布局打算直接构 ...
- Python网络爬虫笔记(四):使用selenium获取动态加载的内容
(一) 说明 上一篇只能下载一页的数据,第2.3.4....100页的数据没法获取,在上一篇的基础上修改了下,使用selenium去获取所有页的href属性值. 使用selenium去模拟浏览器有点 ...
- MATLAB中批量导入.mat文件(每个文件多变量)
一.新建MATLAB script(.m文件):readall_mat.m 二.代码如下: function data = readall_mat(path) % READALL_MAT 读取所有文件 ...
- gulp学习。
安装gulp 安装gulp之前必须先安装node.js,然后在命令行里输入 $ npm install gulp-cli -g (-g 表示全局安装)然后在输入$ gulp -v ,验证,安装完成后再 ...
- AndroidManifest 配置主活动
在activity标签中写如下代码: <activity android:name=".MainActivity" android:label="This is M ...