Odoo中文社区可以通过以下三个域名访问:shine-it.net , odoocn.org,odoo.net.cn

原论坛用户的基本信息和发帖这里都予以保留,请注意:原论坛用户无需重新注册新用户,但是您的密码需要重置

开发人员可以登录gitter讨论组: http://gitter.im/odoo-china/Talk, 需要github账号

如果您登录系统碰到问题,请在微信公众号留言:

【转发】OpenERP开发学习心得



  • 转载自 http://blog.csdn.net/heartrude/article/details/9142463<br /><br />OpenErp学习<br /><br /><br />安装Openoffice<br />在openoffice中安装openerp report designer插件(openerp 7.0中自带)<br /><br /><br />1.保存openoffice文件在英文路径下。如果不保存,send to server的时候会没有反应<br /><br /><br />2. 主要类<br />osv openerp/osv/osv.py<br />在文件中 osv = Model<br />所以osv.osv和osv.Model其实是一样的<br />osv.Model定义在orm.py中<br /><br />report_sxw openerp/report/report_sxw.py<br />logging python库自带<br />import logging<br />_logger = logging.getLogger(name)<br />_logger.error("IntegrityError", exc_info=True)<br /><br /><br />raise osv.except_osv('xinquanda_product', "modify_quantity 0"%(record[0]['quantity']))<br /><br />3.使用openerp report design + openoffice 3.4 + openerp 7.0<br />在send to server的时候会提示UnicodeDecodeError: 'ascii' codec can't decode byte<br />通过在addons\base_report_designer\base_report_designer.py添加如下三行代码解决<br />注意默认使用空格缩进。如果增加的代码使用tab缩进会产生unexpected indent错误<br />import sys<br /><br /><br />def upload_report(self, cr, uid, report_id, file_sxw, file_type, context=None):<br />'''<br />Untested function<br />'''<br />reload(sys)<br />sys.setdefaultencoding('utf8')<br /><br />4.python 一个 *.py就是一个package<br />osv.osv就是osv.py文件内的osv对象<br /><br />5.使用parent_id的时候,使用toolbar产生问题<br /><br /><br />6.selection里面使用中文内容,需要在前面增加u, 比如u'供货商'。否则插入的时候会判断出错<br /><br /><br />7.使用7.0 form如果没有sheet和group,会不显示filed string<br /><br /><br />8.使用openerp report designer自动生成rml会使用in作为object名。会导致在7.0下面无法解析。提示 cannot eval 'xxxx'之类的。修改名字解决问题<br /><br /><br />9.Win7的字体安装直接拖进去是不行的。文件名会变成xxx_1 xxx_2这样(用cmd查看)。所以需要使用cmd的xcopy命令进行放置。否则会安装了新字体,但是还是乱码。使用xcopy进去以后,虽然图形界面看不到该字体安装成功了。但是重启oe之后可以解决乱码问题。如果还不行尝试重启一下系统吧。<br /><br /><br />10.一个工程中存在相同的view_id导致了显示不出来同名menu<br /><br /><br />11. <br />View生成的时候调用的初始化函数<br />def view_init(self, cr, uid, fields_list, context=None):<br /><br />使用菜单栏的导出功能,导出Field数据时调用<br />def export_data(self, cr, uid, ids, fields_to_export, context=None):<br />    <br />加载数据时调用,返回一个id list.代表需要加载的数据<br />def load(self, cr, uid, fields, data, context=None):<br />        """<br />        Attempts to load the data matrix, and returns a list of ids (or<br />        False if there was an error and no id could be generated) and a<br />        list of messages.<br /><br /><br />        The ids are those of the records created and saved (in database), in<br />        the same order they were extracted from the file. They can be passed<br />        directly to :meth:~read<br /><br /><br />    #<br />    # Overload this method if you need a window title which depends on the context<br />    #<br />    def view_header_get(self, cr, user, view_id=None, view_type='form', context=None):<br />        return False<br /><br /><br />// 获取名字,返回名字列表<br />def name_get(self, cr, user, ids, context=None):<br /><br />// 根据参数进行名字查找.返回 (id, name)的tuple列表.相当于先用search进行搜索,然后再用name_get获取名字列表<br />def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100):<br /><br /><br />// 仅仅使用name创建record<br />def name_create(self, cr, uid, name, context=None):<br /><br />create <br />read <br />返回的是dict组成的list<br /><br />write <br />unlink<br /><br />def search(cr, user, args, offset=0, limit=None, order=None, context=None, count=False):<br /><br />cr.execute<br />cr.fetchall<br /><br />// 定义了<br />def func_search(self, cr, uid, obj, name field, args, context):<br /><br />12. pgsql的备份与恢复<br />pg_dump.exe -f d:/backup/1234.backup -F t -h 127.0.0.1 -p 5432 -U openerp -b Erp<br />pg_restore.exe -F t -h 127.0.0.1 -p 5432 -U openerp -d tt d:/backup/1234.backup<br /><br /><br />13.<br />c:&gt;for /f "tokens=1-3 delims=- " %1 in ("%date%") do @echo %1%2%3<br />c:&gt;for /f "tokens=1-3 delims=.: " %1 in ("%time%") do @echo %1%2%3 <br />http://www.jb51.net/article/30539.htm<br /><br />14. <br />report name一样导致了report对应的model调用错误<br /><br />15.<br />select 'cp' || right(cast(pow(10, 10) as varchar) || id, 10) as sn, customer_id as name, '付款' as operation, pay_value as value, date, note from xinquanda_customer_payment <br />union <br />select 'co' || right(cast(pow(10, 10) as varchar) || id, 10) as sn, customer_id as name, '退货' as operation, price_totle as value, date , '' as note from xinquanda_product_customer_out<br />union <br />select 'ci' || right(cast(pow(10, 10) as varchar) || id, 10) as sn, customer_id as name, '供货' as operation, price_totle as value, date , '' as note from xinquanda_product_customer_in;<br /><br /><br />16.有关于view视图的创建与显示<br />1.在.py的对象创建里面定义_auto = False<br />2.所有_column都需要有readonly=True的属性<br />3.sql设定视图创建sql语句或者在__init(self, cr)函数里面创建具体视图<br /><br />如果调用视图的action使用了tree type进行显示,可能会在报错<br /><br />2013-06-19 01:36:24,151 2392 ERROR Erp openerp.osv.orm: read xinquanda.funds.supplier:None<br />None<br />2013-06-19 01:36:24,154 2392 ERROR Erp openerp.osv.osv: Uncaught exception<br />Traceback (most recent call last):<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 131, in wrapper<br />return f(self, dbname, *args, **kwargs)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 197, in execute<br />res = self.execute_cr(cr, uid, obj, method, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 185, in execute_cr<br />return getattr(object, method)(cr, uid, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\orm.py", line 3606, in read<br />select = map(lambda x: isinstance(x, dict) and x['id'] or x, select)<br />TypeError: argument 2 to map() must support iteration<br />2013-06-19 01:36:24,180 2392 ERROR Erp openerp.netsvc: argument 2 to map() must support iteration<br />Traceback (most recent call last):<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\netsvc.py", line 296, in dispatch_rpc<br />result = ExportService.getService(service_name).dispatch(method, params)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\service\web_services.py", line 626, in dispatch<br />res = fn(db, uid, *params)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 188, in execute_kw<br />return self.execute(db, uid, obj, method, *args, **kw or {})<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 131, in wrapper<br />return f(self, dbname, *args, **kwargs)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 197, in execute<br />res = self.execute_cr(cr, uid, obj, method, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 185, in execute_cr<br />return getattr(object, method)(cr, uid, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\orm.py", line 3606, in read<br />select = map(lambda x: isinstance(x, dict) and x['id'] or x, select)<br />TypeError: argument 2 to map() must support iteration<br /><br /><br />17. 直接在view form的field里面写select属性,貌似不能直接实现查询功能。需要添加search view来自定义搜索<br />a. 生成 search_view定义<br /><br />        <record id="xinquanda_product_customer_in_search" model="ir.ui.view"><br />            <field name="name">xinquanda.product.customer.in.search</field><br />            <field name="model">xinquanda.product.customer.in</field><br />            <field name="arch" type="xml"><br /><search string="进货"><br /><field name="name" filter_domain="[('name','ilike',self),]"/><br /><field name="customer_id" filter_domain="[('customer_id','ilike',self),]"/><br /></search><br />            </field><br />        </record><br />b. 在action里面指定需要的 search_view_id<br /><br />        <record id="action_xinquanda_product_customer_in_form" model="ir.actions.act_window"><br />            <field name="name">客户供货</field><br />            <field name="type">ir.actions.act_window</field><br />            <field name="res_model">xinquanda.product.customer.in</field><br />            <field name="view_type">form</field><br />            <field name="view_mode">tree,form</field><br />            <field name="view_id" ref="xinquanda_product_customer_in_tree"/><br /><field name="search_view_id" ref="xinquanda_product_customer_in_search"/><br />        </record><br /><br /><br />18. domain里面operator的集合<br />operator must be a string with a valid comparison operator from this list: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right The semantics of most of these operators are obvious. The child_of operator will look for records who are children or grand-children of a given record, according to the semantics of this model (i.e following the relationship field named by self._parent_name, by default parent_id.<br /><br />[('name', 'like', 'Behave')] =><br />name LIKE '%Behave%'<br /><br /><br />[('name', 'ilike', 'Behave%')] =><br />name LIKE '%Behave%%'<br /><br /><br />[('name', '=like', 'Behave')] =><br />name LIKE 'Behave' (no sense to use it like this)<br /><br /><br />[('name', '=ilike', 'Behave%')] =><br />name LIKE 'Behave%' (with =ilike, we can control more finely the criteria)<br /><br /><br />19. domain不能直接使用<, >等符号作为domain的operator。 这个不是openerp的问题,而是xml标准的问题<br />>          开始标记  &gt;<br /><br /><br /><          结束标记  &lt;<br /><br /><br />"            引号        &quot;<br /><br /><br />'            撇号      &apos;<br /><br /><br />&          "&"符      &amp;<br /><br />20. 有name_get函数的列如果要实现查找,需要对应实现name_search函数<br />def name_get(self, cr, uid, ids, context=None):<br />if isinstance(ids, (list, tuple)) and not len(ids):<br />return []<br />if isinstance(ids, (long, int)):<br />ids = [ids]<br />reads = self.read(cr, uid, ids, ['name','parent_id'], context=context)<br />res = []<br /><br /><br />for record in reads:<br />name = record['name']<br />if record['parent_id'] and record['parent_id'][1] != u'所有货物':<br />name = record['parent_id'][1]+'/'+name<br />res.append((record['id'], name))<br />return res<br /><br /><br />def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100):<br />_logger = logging.getLogger(name)<br />_logger.error("name_search name=%s args=%s operator=%s context=%s"%(name, args, operator, context), exc_info=True)<br /><br />if name == '':<br />result = super(xinquanda_product_category, self).name_search(cr, user, name, args, operator, context, limit)<br />_logger.error("1 name_search result=%s"%(result), exc_info=True)<br />return result<br />#去除父类名<br />nameIndex = name.rfind('/')<br />if nameIndex != -1:<br />name = name[nameIndex+1:]<br /><br />_logger.error("2 name_search name=%s"%(name), exc_info=True)<br /><br />result = super(xinquanda_product_category, self).name_search(cr, user, name, args, operator, context, limit)<br />_logger.error("2 name_search result=%s"%(result), exc_info=True)<br />return result<br /><br />21. 统计功能的另一种实现<br />直接修改search和read函数。而非通过数据库试图实现。<br />class xinquanda_statistics_product_period(osv.osv):<br /><br />_name = 'xinquanda.statistics.product.period'<br />_description = u'货物销售时间段统计'<br />_auto = False<br /><br />_search_context = {}<br /><br />def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):<br />_logger = logging.getLogger(name)<br />_logger.error("search args:%s, offset=%s limit=%s context:%s order=%s"%(<br />args,<br />offset,<br />limit,<br />context,<br />order), exc_info=True)<br /><br />_search_context = {}<br />date_start = '2010-01-01'<br />date_end = '2100-12-31'<br /><br />for arg in args:<br />if arg[0] == 'date_start':<br />self._search_context['date_start'] = arg[2]<br />if arg[0] == 'date_end':<br />self._search_context['date_end'] = arg[2]<br />if arg[0] == 'product_id':<br />self._search_context['id']<br /><br /><br />whereSql = ' where true'<br />if self._search_context.get('date_start'):<br />date_start = self._search_context.get('date_start')<br />whereSql = whereSql + " and i.date >= '%s'"%(date_start)<br /><br />if self._search_context.get('date_end'):<br />date_end = self._search_context.get('date_end')<br />whereSql = whereSql + (" and i.date <= '%s'"%(date_end))<br /><br /><br />groupSql = ' group by product_id'<br />orderSql = ''<br />offsetSql = ''<br />limitSql = ''<br /><br />if order:<br />orderSql = 'order by %s'%(order)<br /><br />if offset > 0:<br />offsetSql = ' offset %d'%offset<br />if limit:<br />limitSql = ' limit %d'%limit<br /><br />selectSql = """select product_id as id, product_id, '%s' as date_start, '%s' as date_end, sum(l.quantity) as quantity_totle, sum(l.quantity * l.price_sale) as price_totle, sum(l.quantity * (l.price_sale - p.price_buy)) as profits from xinquanda_product_customer_in_list as l join xinquanda_product as p on l.product_id = p.id join xinquanda_product_customer_in as i on l.in_id = i.id %s %s %s %s %s"""%(date_start, date_end, whereSql, groupSql, orderSql, offsetSql, limitSql)<br /><br />_logger.error("search selectSql=%s"%(<br />selectSql), exc_info=True)<br /><br />cr.execute(selectSql)<br />records = cr.fetchall()<br /><br />result = []<br />for record in records:<br />result.append(record[0])<br /><br />return result<br /><br />def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):<br />_logger = logging.getLogger(name)<br />_logger.error("read ids:%s, fields:%s context:%s load=%s self._search_context=%s"%(<br />ids, <br />fields, <br />context, <br />load,<br />self._search_context), exc_info=True)<br /><br />date_start = '2010-01-01'<br />date_end = '2100-12-31'<br /><br />whereSql = ' where true'<br />if self._search_context.get('date_start'):<br />date_start = self._search_context.get('date_start')<br />whereSql = whereSql + " and i.date >= '%s'"%(date_start)<br /><br />if self._search_context.get('date_end'):<br />date_end = self._search_context.get('date_end')<br />whereSql = whereSql + (" and i.date <= '%s'"%(date_end))<br /><br />if isinstance(ids, (int, long)):<br />ids = (ids,)<br />if isinstance(ids, tuple):<br />ids = list(ids,)<br /><br /><br />if len(ids) > 0:<br />temp = '%s'%(ids)<br />temp = temp.replace('[', '(', 1)<br />temp = temp.replace(']', ')', 1)<br />whereSql = whereSql + ' and product_id in ' + temp<br /><br />groupSql = ' group by product_id;'<br /><br /><br />selectSql = """select product_id as id, product_id, '%s' as date_start, '%s' as date_end, sum(l.quantity) as quantity_totle, sum(l.quantity * l.price_sale) as price_totle, sum(l.quantity * (l.price_sale - p.price_buy)) as profits from xinquanda_product_customer_in_list as l join xinquanda_product as p on l.product_id = p.id join xinquanda_product_customer_in as i on l.in_id = i.id %s %s"""%(date_start, date_end, whereSql, groupSql)<br /><br />_logger.error("read selectSql=%s"%(<br />selectSql), exc_info=True)<br /><br />cr.execute(selectSql)<br />result = cr.fetchall()<br /><br /><br />#把result转化为record要求的dict格式<br />colum_field = ['id', 'product_id', 'date_start', 'date_end', 'quantity_totle', 'price_totle', 'profits']<br />read_result = []<br />for record in result:<br />read_record = {}<br />index = 0<br />while index < len(colum_field):<br />read_record[colum_field[index]] = record[index]<br />index = index + 1<br />read_result.append(read_record)<br /><br /><br />#清空search<br />self._search_context = {}<br /><br />return read_result<br /><br />_columns = {<br />'product_id' : fields.many2one('xinquanda.product', '货物', readonly=True, select=True),<br />'date_start': fields.date('起始日期', readonly=True, required=True),<br />'date_end': fields.date('结束日期', readonly=True, required=True),<br />'quantity_totle' : fields.integer('销售总量', readonly=True, select=True),<br />'price_totle' : fields.float('销售总额', readonly=True),<br />'profits' : fields.float('利润', readonly=True),<br /> }<br /><br />xinquanda_statistics_product_period()#对象定义结束<br /><br /><br />22. 权限分配可以开启技术菜单。通过配置组的权限来实现<br /><br /><br />23. 设置表格默认列数。在action的xml里面增加<field name="limit">lines number</field><br /><br /> <br /><br />24.设置表格默认顺序。在py定义里面增加 _order = 'field name [desc]'



  • 转载自 http://blog.csdn.net/heartrude/article/details/9142463<br /><br />OpenErp学习<br /><br /><br />安装Openoffice<br />在openoffice中安装openerp report designer插件(openerp 7.0中自带)<br /><br /><br />1.保存openoffice文件在英文路径下。如果不保存,send to server的时候会没有反应<br /><br /><br />2. 主要类<br />osv openerp/osv/osv.py<br />在文件中 osv = Model<br />所以osv.osv和osv.Model其实是一样的<br />osv.Model定义在orm.py中<br /><br />report_sxw openerp/report/report_sxw.py<br />logging python库自带<br />import logging<br />_logger = logging.getLogger(name)<br />_logger.error("IntegrityError", exc_info=True)<br /><br /><br />raise osv.except_osv('xinquanda_product', "modify_quantity 0"%(record[0]['quantity']))<br /><br />3.使用openerp report design + openoffice 3.4 + openerp 7.0<br />在send to server的时候会提示UnicodeDecodeError: 'ascii' codec can't decode byte<br />通过在addons\base_report_designer\base_report_designer.py添加如下三行代码解决<br />注意默认使用空格缩进。如果增加的代码使用tab缩进会产生unexpected indent错误<br />import sys<br /><br /><br />def upload_report(self, cr, uid, report_id, file_sxw, file_type, context=None):<br />'''<br />Untested function<br />'''<br />reload(sys)<br />sys.setdefaultencoding('utf8')<br /><br />4.python 一个 *.py就是一个package<br />osv.osv就是osv.py文件内的osv对象<br /><br />5.使用parent_id的时候,使用toolbar产生问题<br /><br /><br />6.selection里面使用中文内容,需要在前面增加u, 比如u'供货商'。否则插入的时候会判断出错<br /><br /><br />7.使用7.0 form如果没有sheet和group,会不显示filed string<br /><br /><br />8.使用openerp report designer自动生成rml会使用in作为object名。会导致在7.0下面无法解析。提示 cannot eval 'xxxx'之类的。修改名字解决问题<br /><br /><br />9.Win7的字体安装直接拖进去是不行的。文件名会变成xxx_1 xxx_2这样(用cmd查看)。所以需要使用cmd的xcopy命令进行放置。否则会安装了新字体,但是还是乱码。使用xcopy进去以后,虽然图形界面看不到该字体安装成功了。但是重启oe之后可以解决乱码问题。如果还不行尝试重启一下系统吧。<br /><br /><br />10.一个工程中存在相同的view_id导致了显示不出来同名menu<br /><br /><br />11. <br />View生成的时候调用的初始化函数<br />def view_init(self, cr, uid, fields_list, context=None):<br /><br />使用菜单栏的导出功能,导出Field数据时调用<br />def export_data(self, cr, uid, ids, fields_to_export, context=None):<br />    <br />加载数据时调用,返回一个id list.代表需要加载的数据<br />def load(self, cr, uid, fields, data, context=None):<br />        """<br />        Attempts to load the data matrix, and returns a list of ids (or<br />        False if there was an error and no id could be generated) and a<br />        list of messages.<br /><br /><br />        The ids are those of the records created and saved (in database), in<br />        the same order they were extracted from the file. They can be passed<br />        directly to :meth:~read<br /><br /><br />    #<br />    # Overload this method if you need a window title which depends on the context<br />    #<br />    def view_header_get(self, cr, user, view_id=None, view_type='form', context=None):<br />        return False<br /><br /><br />// 获取名字,返回名字列表<br />def name_get(self, cr, user, ids, context=None):<br /><br />// 根据参数进行名字查找.返回 (id, name)的tuple列表.相当于先用search进行搜索,然后再用name_get获取名字列表<br />def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100):<br /><br /><br />// 仅仅使用name创建record<br />def name_create(self, cr, uid, name, context=None):<br /><br />create <br />read <br />返回的是dict组成的list<br /><br />write <br />unlink<br /><br />def search(cr, user, args, offset=0, limit=None, order=None, context=None, count=False):<br /><br />cr.execute<br />cr.fetchall<br /><br />// 定义了<br />def func_search(self, cr, uid, obj, name field, args, context):<br /><br />12. pgsql的备份与恢复<br />pg_dump.exe -f d:/backup/1234.backup -F t -h 127.0.0.1 -p 5432 -U openerp -b Erp<br />pg_restore.exe -F t -h 127.0.0.1 -p 5432 -U openerp -d tt d:/backup/1234.backup<br /><br /><br />13.<br />c:&gt;for /f "tokens=1-3 delims=- " %1 in ("%date%") do @echo %1%2%3<br />c:&gt;for /f "tokens=1-3 delims=.: " %1 in ("%time%") do @echo %1%2%3 <br />http://www.jb51.net/article/30539.htm<br /><br />14. <br />report name一样导致了report对应的model调用错误<br /><br />15.<br />select 'cp' || right(cast(pow(10, 10) as varchar) || id, 10) as sn, customer_id as name, '付款' as operation, pay_value as value, date, note from xinquanda_customer_payment <br />union <br />select 'co' || right(cast(pow(10, 10) as varchar) || id, 10) as sn, customer_id as name, '退货' as operation, price_totle as value, date , '' as note from xinquanda_product_customer_out<br />union <br />select 'ci' || right(cast(pow(10, 10) as varchar) || id, 10) as sn, customer_id as name, '供货' as operation, price_totle as value, date , '' as note from xinquanda_product_customer_in;<br /><br /><br />16.有关于view视图的创建与显示<br />1.在.py的对象创建里面定义_auto = False<br />2.所有_column都需要有readonly=True的属性<br />3.sql设定视图创建sql语句或者在__init(self, cr)函数里面创建具体视图<br /><br />如果调用视图的action使用了tree type进行显示,可能会在报错<br /><br />2013-06-19 01:36:24,151 2392 ERROR Erp openerp.osv.orm: read xinquanda.funds.supplier:None<br />None<br />2013-06-19 01:36:24,154 2392 ERROR Erp openerp.osv.osv: Uncaught exception<br />Traceback (most recent call last):<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 131, in wrapper<br />return f(self, dbname, *args, **kwargs)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 197, in execute<br />res = self.execute_cr(cr, uid, obj, method, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 185, in execute_cr<br />return getattr(object, method)(cr, uid, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\orm.py", line 3606, in read<br />select = map(lambda x: isinstance(x, dict) and x['id'] or x, select)<br />TypeError: argument 2 to map() must support iteration<br />2013-06-19 01:36:24,180 2392 ERROR Erp openerp.netsvc: argument 2 to map() must support iteration<br />Traceback (most recent call last):<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\netsvc.py", line 296, in dispatch_rpc<br />result = ExportService.getService(service_name).dispatch(method, params)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\service\web_services.py", line 626, in dispatch<br />res = fn(db, uid, *params)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 188, in execute_kw<br />return self.execute(db, uid, obj, method, *args, **kw or {})<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 131, in wrapper<br />return f(self, dbname, *args, **kwargs)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 197, in execute<br />res = self.execute_cr(cr, uid, obj, method, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\osv.py", line 185, in execute_cr<br />return getattr(object, method)(cr, uid, *args, **kw)<br /> File "D:\programs\GreenOpenERP-7.0-20130428-232407\openerp\osv\orm.py", line 3606, in read<br />select = map(lambda x: isinstance(x, dict) and x['id'] or x, select)<br />TypeError: argument 2 to map() must support iteration<br /><br /><br />17. 直接在view form的field里面写select属性,貌似不能直接实现查询功能。需要添加search view来自定义搜索<br />a. 生成 search_view定义<br /><br />        <record id="xinquanda_product_customer_in_search" model="ir.ui.view"><br />            <field name="name">xinquanda.product.customer.in.search</field><br />            <field name="model">xinquanda.product.customer.in</field><br />            <field name="arch" type="xml"><br /><search string="进货"><br /><field name="name" filter_domain="[('name','ilike',self),]"/><br /><field name="customer_id" filter_domain="[('customer_id','ilike',self),]"/><br /></search><br />            </field><br />        </record><br />b. 在action里面指定需要的 search_view_id<br /><br />        <record id="action_xinquanda_product_customer_in_form" model="ir.actions.act_window"><br />            <field name="name">客户供货</field><br />            <field name="type">ir.actions.act_window</field><br />            <field name="res_model">xinquanda.product.customer.in</field><br />            <field name="view_type">form</field><br />            <field name="view_mode">tree,form</field><br />            <field name="view_id" ref="xinquanda_product_customer_in_tree"/><br /><field name="search_view_id" ref="xinquanda_product_customer_in_search"/><br />        </record><br /><br /><br />18. domain里面operator的集合<br />operator must be a string with a valid comparison operator from this list: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right The semantics of most of these operators are obvious. The child_of operator will look for records who are children or grand-children of a given record, according to the semantics of this model (i.e following the relationship field named by self._parent_name, by default parent_id.<br /><br />[('name', 'like', 'Behave')] =><br />name LIKE '%Behave%'<br /><br /><br />[('name', 'ilike', 'Behave%')] =><br />name LIKE '%Behave%%'<br /><br /><br />[('name', '=like', 'Behave')] =><br />name LIKE 'Behave' (no sense to use it like this)<br /><br /><br />[('name', '=ilike', 'Behave%')] =><br />name LIKE 'Behave%' (with =ilike, we can control more finely the criteria)<br /><br /><br />19. domain不能直接使用<, >等符号作为domain的operator。 这个不是openerp的问题,而是xml标准的问题<br />>          开始标记  &gt;<br /><br /><br /><          结束标记  &lt;<br /><br /><br />"            引号        &quot;<br /><br /><br />'            撇号      &apos;<br /><br /><br />&          "&"符      &amp;<br /><br />20. 有name_get函数的列如果要实现查找,需要对应实现name_search函数<br />def name_get(self, cr, uid, ids, context=None):<br />if isinstance(ids, (list, tuple)) and not len(ids):<br />return []<br />if isinstance(ids, (long, int)):<br />ids = [ids]<br />reads = self.read(cr, uid, ids, ['name','parent_id'], context=context)<br />res = []<br /><br /><br />for record in reads:<br />name = record['name']<br />if record['parent_id'] and record['parent_id'][1] != u'所有货物':<br />name = record['parent_id'][1]+'/'+name<br />res.append((record['id'], name))<br />return res<br /><br /><br />def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100):<br />_logger = logging.getLogger(name)<br />_logger.error("name_search name=%s args=%s operator=%s context=%s"%(name, args, operator, context), exc_info=True)<br /><br />if name == '':<br />result = super(xinquanda_product_category, self).name_search(cr, user, name, args, operator, context, limit)<br />_logger.error("1 name_search result=%s"%(result), exc_info=True)<br />return result<br />#去除父类名<br />nameIndex = name.rfind('/')<br />if nameIndex != -1:<br />name = name[nameIndex+1:]<br /><br />_logger.error("2 name_search name=%s"%(name), exc_info=True)<br /><br />result = super(xinquanda_product_category, self).name_search(cr, user, name, args, operator, context, limit)<br />_logger.error("2 name_search result=%s"%(result), exc_info=True)<br />return result<br /><br />21. 统计功能的另一种实现<br />直接修改search和read函数。而非通过数据库试图实现。<br />class xinquanda_statistics_product_period(osv.osv):<br /><br />_name = 'xinquanda.statistics.product.period'<br />_description = u'货物销售时间段统计'<br />_auto = False<br /><br />_search_context = {}<br /><br />def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):<br />_logger = logging.getLogger(name)<br />_logger.error("search args:%s, offset=%s limit=%s context:%s order=%s"%(<br />args,<br />offset,<br />limit,<br />context,<br />order), exc_info=True)<br /><br />_search_context = {}<br />date_start = '2010-01-01'<br />date_end = '2100-12-31'<br /><br />for arg in args:<br />if arg[0] == 'date_start':<br />self._search_context['date_start'] = arg[2]<br />if arg[0] == 'date_end':<br />self._search_context['date_end'] = arg[2]<br />if arg[0] == 'product_id':<br />self._search_context['id']<br /><br /><br />whereSql = ' where true'<br />if self._search_context.get('date_start'):<br />date_start = self._search_context.get('date_start')<br />whereSql = whereSql + " and i.date >= '%s'"%(date_start)<br /><br />if self._search_context.get('date_end'):<br />date_end = self._search_context.get('date_end')<br />whereSql = whereSql + (" and i.date <= '%s'"%(date_end))<br /><br /><br />groupSql = ' group by product_id'<br />orderSql = ''<br />offsetSql = ''<br />limitSql = ''<br /><br />if order:<br />orderSql = 'order by %s'%(order)<br /><br />if offset > 0:<br />offsetSql = ' offset %d'%offset<br />if limit:<br />limitSql = ' limit %d'%limit<br /><br />selectSql = """select product_id as id, product_id, '%s' as date_start, '%s' as date_end, sum(l.quantity) as quantity_totle, sum(l.quantity * l.price_sale) as price_totle, sum(l.quantity * (l.price_sale - p.price_buy)) as profits from xinquanda_product_customer_in_list as l join xinquanda_product as p on l.product_id = p.id join xinquanda_product_customer_in as i on l.in_id = i.id %s %s %s %s %s"""%(date_start, date_end, whereSql, groupSql, orderSql, offsetSql, limitSql)<br /><br />_logger.error("search selectSql=%s"%(<br />selectSql), exc_info=True)<br /><br />cr.execute(selectSql)<br />records = cr.fetchall()<br /><br />result = []<br />for record in records:<br />result.append(record[0])<br /><br />return result<br /><br />def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):<br />_logger = logging.getLogger(name)<br />_logger.error("read ids:%s, fields:%s context:%s load=%s self._search_context=%s"%(<br />ids, <br />fields, <br />context, <br />load,<br />self._search_context), exc_info=True)<br /><br />date_start = '2010-01-01'<br />date_end = '2100-12-31'<br /><br />whereSql = ' where true'<br />if self._search_context.get('date_start'):<br />date_start = self._search_context.get('date_start')<br />whereSql = whereSql + " and i.date >= '%s'"%(date_start)<br /><br />if self._search_context.get('date_end'):<br />date_end = self._search_context.get('date_end')<br />whereSql = whereSql + (" and i.date <= '%s'"%(date_end))<br /><br />if isinstance(ids, (int, long)):<br />ids = (ids,)<br />if isinstance(ids, tuple):<br />ids = list(ids,)<br /><br /><br />if len(ids) > 0:<br />temp = '%s'%(ids)<br />temp = temp.replace('[', '(', 1)<br />temp = temp.replace(']', ')', 1)<br />whereSql = whereSql + ' and product_id in ' + temp<br /><br />groupSql = ' group by product_id;'<br /><br /><br />selectSql = """select product_id as id, product_id, '%s' as date_start, '%s' as date_end, sum(l.quantity) as quantity_totle, sum(l.quantity * l.price_sale) as price_totle, sum(l.quantity * (l.price_sale - p.price_buy)) as profits from xinquanda_product_customer_in_list as l join xinquanda_product as p on l.product_id = p.id join xinquanda_product_customer_in as i on l.in_id = i.id %s %s"""%(date_start, date_end, whereSql, groupSql)<br /><br />_logger.error("read selectSql=%s"%(<br />selectSql), exc_info=True)<br /><br />cr.execute(selectSql)<br />result = cr.fetchall()<br /><br /><br />#把result转化为record要求的dict格式<br />colum_field = ['id', 'product_id', 'date_start', 'date_end', 'quantity_totle', 'price_totle', 'profits']<br />read_result = []<br />for record in result:<br />read_record = {}<br />index = 0<br />while index < len(colum_field):<br />read_record[colum_field[index]] = record[index]<br />index = index + 1<br />read_result.append(read_record)<br /><br /><br />#清空search<br />self._search_context = {}<br /><br />return read_result<br /><br />_columns = {<br />'product_id' : fields.many2one('xinquanda.product', '货物', readonly=True, select=True),<br />'date_start': fields.date('起始日期', readonly=True, required=True),<br />'date_end': fields.date('结束日期', readonly=True, required=True),<br />'quantity_totle' : fields.integer('销售总量', readonly=True, select=True),<br />'price_totle' : fields.float('销售总额', readonly=True),<br />'profits' : fields.float('利润', readonly=True),<br /> }<br /><br />xinquanda_statistics_product_period()#对象定义结束<br /><br /><br />22. 权限分配可以开启技术菜单。通过配置组的权限来实现<br /><br /><br />23. 设置表格默认列数。在action的xml里面增加<field name="limit">lines number</field><br /><br /> <br /><br />24.设置表格默认顺序。在py定义里面增加 _order = 'field name [desc]'



  • 收藏......



  • 收藏先!



  • 火速回复。。。mark~



  • 学习了 <br /><br />23. 设置表格默认列数。在action的xml里面增加<field name="limit">lines number</field><br /><br />这个测试了,是默认行数,可能楼主 笔误,不写时,是80



  • 收藏......



  • 收藏中 。。。。



  • mark



  • 收藏只能通过留言的方式?没找到收藏按钮哪。。。


登录后回复
 

与 Odoo 中文社区 的连接断开,我们正在尝试重连,请耐心等待