会计收入报表总结
整个开发流程,先建一个菜单按钮,选择之后弹出框,然后选值之后根据对应的值导出excel报表,第一天先跑通能有弹出框,能导出excel报表,第二天写sql语句,将sql查询到的值传给前端,生成excel报表数据,第三天新建模型account.income.tax,建立多个会计科目对应一个税目的对应关系,然后将税率,税后收入两列填入excel表
第四天,用RPC建立和SAAS台账系统之间的联系,调用SAAS中的数据
第五天,完善查询条件
总结下逻辑思路,新建立模型account.income.tax,其中两个字段,一个是会计科目,一个是税率,写sql语句需要分类,根据会计科目,客户名称和期间来分类,而会计科目是新建模型中所有的值,客户名称和期间是需要根据页面上所选来判断的,所以要区分开来写,分别是页面上有值,和页面上没有值的情况,整合好sql查询语句后,将查询到的值传给解析的函数,解析函数再将值传给生成excel的函数
总结一下遇到的难点
1.界面
(1)field在一行内显示
<group>
<group>
<field name="start_period" string="请选择期间"/>
</group>
<group>
<field name="end_period" string="请选择期间"/>
</group>
</group>
第一个group是一行
里面的两个group表示一个在左边,一个在右边
(2)能选择多个对象
<group>
<field name="customer" string="请选择客户" widget="many2many_tags"
options="{'no_create': True,'no_open':True, 'no_create_edit':True, 'no_quick_create':True}"/>
</group>
添加widget="many2many_tags"
导出excel一直报错,原因是没加data
2.生成excel的流程
(1)首先在wizard中定义瞬时模型,按钮的name方法返回
return self.env['report'].get_action(self, report_name, data=data)
注意data的参数必须要加上
(2)定义xml文件,其中包含report和record标签
report中的id值是controllers中的py文件def方法名
report的name属性是刚刚定义return返回的report_name,模型名.id
model属性是定义wizard瞬时模型的name
record标签中
id属性和report中id相同
<field name="report_rml">/report/income_statement.report_income_detail</field>
中间的路径是controllers中@http.route中的路径
(3)定义controllers中的py文件,def 方法名是report和record的id值
3.sql语句
分为有条件的时候,和没有条件的时候,没有条件就默认为全部,要把这一部分sql语句分开写
cr = self._cr
sql = ''' '''
cr.execute(sql)
result = cr.fetchall()
# result 是查找到的所有记录
4.解析数据
传参形式[{},{},{}]
然后获取的时候
data = simplejson.loads(data['options'])
result = data.get('data')
result.get('', False)
用字典.get(key, False)的形式,即使没有值也能用False代替,这样不会报错
5.新建模型account.income.tax
模型有两个字段account_id和tax_id,分别要和account.account,account_tax关联,数据需要新建菜单,在页面上自己进行添加
6.RPC
首先先定义模型
# -*- coding: utf-8 -*-
import xmlrpclib
class OdooRpc(object):
def __init__(self, url, db, username, password):
self.url = url
self.db = db
self.username = username
self.password = password
def method(self, model_name, function_name, domain):
common = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(self.url))
uid = common.authenticate(self.db, self.username, self.password, {})
models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(self.url))
company_id = models.execute_kw(self.db, uid, self.password, model_name, function_name, domain)
return company_id
然后调用的时候传参数
odoorpc = OdooRpc(url=self.env['ir.config_parameter'].get_param('income.statement.url'),
db=self.env['ir.config_parameter'].get_param('income.statement.db'),
username=self.env['ir.config_parameter'].get_param('income.statement.username'),
password=self.env['ir.config_parameter'].get_param('income.statement.password'))
id = odoorpc.method(model_name='res.company', function_name='search', domain=[[['code', '=', company_code]]])
遇到的报错及知识点
1.<bound method account.income.wizard.report_parameter of account.income.wizard(80,)> is not JSON serializable
先调用一下方法,不能直接传,因为是对象,要将调用方法返回的结果传给前端
2.sql语句要(),先用tuple转换
3.列表中套列表
[a,b,c]
4.sql语句
5.如何运用新建的模型
KeyError: 'account.income.tax'
在init.py文件中引入
6.去掉tuple中一个元素后面的逗号
字符串拼接方式
7.Access Denied by ACLs for operation: read, uid: 199, model: account.income.tax
设置权限,只要新建一个表都要设置权限
8.current transaction is aborted, commands ignored until end of transaction block
就是创建菜单,然后在菜单中创建记录,把流程走通就可以了,之后的关系会自动维护
9.python中用excel函数xlwt.Formula()
10.代替语法
{item}.format(item='')
11.browse和search的区别
search为了查找id,browse取得整个对象
#get the value of others fields in the table or walking through many2one relations fields, like:
item_location = fields.Char(related='item_location', string = 'Item location')
good:
for record in self.browse():
bad:
for foo in bars:
record = self.browse()
12.hash()来保证数据的唯一性
hash(str())
dictionary = {}
res1 = [customer_name,start_time]
dictionary.update({
hash(str(res1)): demo
})
res2 = [partner_name,start_time]
if dictionary.get(hash(str(res2))):
tmp.update(dictionary.get(hash(str(res2))))
#tmp是要添加数据的字典
13.遇到u''的值转换为字符串
c = u'\u9752\u5c9b\u7231\u6e90\u98df\u54c1\u6709\u9650\u516c\u53f8'
b = c.encode('utf-8')
print(b)
14.获取系统参数模型中的键的值
url = self.env['ir.config_parameter'].get_param('income.statement.url')
查找代码的技巧
(1)查找form视图的时候,选择编辑Form视图,外部ID在代码中搜索就可以找到对应的视图了
(2)查找field字段在代码中找字段名
(3)res = self.env['account.move'].search([], limit=1)
dir(res)可以看到odoo自定义的很多方法