odoo之ERP系统

odoo大纲

第一部分:数据库postgressql 大象


第二部分:ORM(API)


第三部分:客户端


python软件写:

.py文件

包含两部分:1、自定义部分,由自己写,定义类和功能。

2、继承部分,针对的是原生的模块,继承他原有的功能,添加新的方法。


.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代码  收藏代码

 

  1. selection: 下拉框字段。定义一个下拉框,允许用户选择值。如:'state': fields.selection((('n','Unconfirmed'),('c','Confirmed')),'State', required=True),这表示state字段有两个选项('n','Unconfirmed')('c','Confirmed')。  

 

 function

 

Python代码  收藏代码

 

  1. #函数型,该类型的字段,字段值由函数计算而得,不存储在数据表中。其定义格式为:  

  2. fields.function(fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='float', fnct_search=None, obj=None, method=False, store=True)  

  3.   

  4.  type 是函数返回值的类型。

  5. #· method True表示本字段的函数是对象的一个方法,为False表示是全局函数,不是对象的方法。如果method=Trueobj指定method的对象。

  6.  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 idfield_name是本字段名,当一个函数用于多个函数字段类型时,本参数可区分字段。args'arg=None'传进来的参数。

  7. #· 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)

  8. #· fcnt_search 定义该字段的搜索行为。如果method = true, 其格式为:def fcnt_search(self, cr, uid, obj, field_name, args),否则格式为:def fcnt_search(cr, uid, obj, field_name, args)  

  9. #· 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

 

  1. #关联字段,表示本字段引用关联表中的某字段。  

  2. 格式为:fields.related(关系字段,引用字段,type, relation, string, ...),关系字段是本对象的某字段(通常是one2many or many2many),引用字段是通过关系字段关联的数据表的字段,type是引用字段的类型,  

  3.   

  4. 如果typemany2one or many2many, relation指明关联表。例子如下:  

  5. 'address': fields.one2many('res.partner.address''partner_id''Contacts'),  

  6. 'city':fields.related('address','city',type='char', string='City'),  

  7. 'country':fields.related('address','country_id',type='many2one', relation='res.country', string='Country'),  

  8. 这里,city引用addresscity字段,country引用addresscountry对象。在address的关联对象res.partner.address中,country_idmany2one类型的字段,所以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的值设定其它字段的缺省值,例如,可以通过程序代码,如果zip200000city设为“上海”,如果zip100000city为“北京”。

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:
域条件,缺省值:[]。在many2manymany2one类型中,字段值是关联表的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的表达式,返回TrueFalse

 

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=100): 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)

 


 


 

转载于:https://www.cnblogs.com/1314520xh/p/6885239.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值